Mercurial > hg > truffle
annotate src/os/linux/vm/os_linux.cpp @ 5693:0356d95f01ba
While inlining, ensure proper anchoring of things that where anchored to the StartNode
Fix killCFG case where some dead nodes would not be removed, leading to later NullPointerExceptions
Fix Switch nodes simplification in case the node of the remaining successor changes because of deleting the other branches
Fix addDuplicates : do not patch inputs to the outer world if these inputs would point to an other graph
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Tue, 26 Jun 2012 16:43:51 +0200 |
parents | 897b7d18bebc |
children | 957c266d8bc5 |
rev | line source |
---|---|
0 | 1 /* |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1537
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1537
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:
1537
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 // no precompiled headers |
26 #include "classfile/classLoader.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "classfile/vmSymbols.hpp" | |
29 #include "code/icBuffer.hpp" | |
30 #include "code/vtableStubs.hpp" | |
31 #include "compiler/compileBroker.hpp" | |
32 #include "interpreter/interpreter.hpp" | |
33 #include "jvm_linux.h" | |
34 #include "memory/allocation.inline.hpp" | |
35 #include "memory/filemap.hpp" | |
36 #include "mutex_linux.inline.hpp" | |
37 #include "oops/oop.inline.hpp" | |
38 #include "os_share_linux.hpp" | |
39 #include "prims/jniFastGetField.hpp" | |
40 #include "prims/jvm.h" | |
41 #include "prims/jvm_misc.hpp" | |
42 #include "runtime/arguments.hpp" | |
43 #include "runtime/extendedPC.hpp" | |
44 #include "runtime/globals.hpp" | |
45 #include "runtime/interfaceSupport.hpp" | |
46 #include "runtime/java.hpp" | |
47 #include "runtime/javaCalls.hpp" | |
48 #include "runtime/mutexLocker.hpp" | |
49 #include "runtime/objectMonitor.hpp" | |
50 #include "runtime/osThread.hpp" | |
51 #include "runtime/perfMemory.hpp" | |
52 #include "runtime/sharedRuntime.hpp" | |
53 #include "runtime/statSampler.hpp" | |
54 #include "runtime/stubRoutines.hpp" | |
55 #include "runtime/threadCritical.hpp" | |
56 #include "runtime/timer.hpp" | |
57 #include "services/attachListener.hpp" | |
58 #include "services/runtimeService.hpp" | |
59 #include "thread_linux.inline.hpp" | |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
60 #include "utilities/decoder.hpp" |
1972 | 61 #include "utilities/defaultStream.hpp" |
62 #include "utilities/events.hpp" | |
63 #include "utilities/growableArray.hpp" | |
64 #include "utilities/vmError.hpp" | |
65 #ifdef TARGET_ARCH_x86 | |
66 # include "assembler_x86.inline.hpp" | |
67 # include "nativeInst_x86.hpp" | |
68 #endif | |
69 #ifdef TARGET_ARCH_sparc | |
70 # include "assembler_sparc.inline.hpp" | |
71 # include "nativeInst_sparc.hpp" | |
72 #endif | |
73 #ifdef TARGET_ARCH_zero | |
74 # include "assembler_zero.inline.hpp" | |
75 # include "nativeInst_zero.hpp" | |
76 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2130
diff
changeset
|
77 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2130
diff
changeset
|
78 # include "assembler_arm.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2130
diff
changeset
|
79 # include "nativeInst_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2130
diff
changeset
|
80 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2130
diff
changeset
|
81 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2130
diff
changeset
|
82 # include "assembler_ppc.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2130
diff
changeset
|
83 # include "nativeInst_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2130
diff
changeset
|
84 #endif |
1972 | 85 #ifdef COMPILER1 |
86 #include "c1/c1_Runtime1.hpp" | |
87 #endif | |
88 #ifdef COMPILER2 | |
89 #include "opto/runtime.hpp" | |
90 #endif | |
0 | 91 |
92 // put OS-includes here | |
93 # include <sys/types.h> | |
94 # include <sys/mman.h> | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
95 # include <sys/stat.h> |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
96 # include <sys/select.h> |
0 | 97 # include <pthread.h> |
98 # include <signal.h> | |
99 # include <errno.h> | |
100 # include <dlfcn.h> | |
101 # include <stdio.h> | |
102 # include <unistd.h> | |
103 # include <sys/resource.h> | |
104 # include <pthread.h> | |
105 # include <sys/stat.h> | |
106 # include <sys/time.h> | |
107 # include <sys/times.h> | |
108 # include <sys/utsname.h> | |
109 # include <sys/socket.h> | |
110 # include <sys/wait.h> | |
111 # include <pwd.h> | |
112 # include <poll.h> | |
113 # include <semaphore.h> | |
114 # include <fcntl.h> | |
115 # include <string.h> | |
116 # include <syscall.h> | |
117 # include <sys/sysinfo.h> | |
118 # include <gnu/libc-version.h> | |
119 # include <sys/ipc.h> | |
120 # include <sys/shm.h> | |
121 # include <link.h> | |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
122 # include <stdint.h> |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
123 # include <inttypes.h> |
2033
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
124 # include <sys/ioctl.h> |
0 | 125 |
126 #define MAX_PATH (2 * K) | |
127 | |
128 // for timer info max values which include all bits | |
129 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) | |
130 | |
2204
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
131 #define LARGEPAGES_BIT (1 << 6) |
0 | 132 //////////////////////////////////////////////////////////////////////////////// |
133 // global variables | |
134 julong os::Linux::_physical_memory = 0; | |
135 | |
136 address os::Linux::_initial_thread_stack_bottom = NULL; | |
137 uintptr_t os::Linux::_initial_thread_stack_size = 0; | |
138 | |
139 int (*os::Linux::_clock_gettime)(clockid_t, struct timespec *) = NULL; | |
140 int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL; | |
141 Mutex* os::Linux::_createThread_lock = NULL; | |
142 pthread_t os::Linux::_main_thread; | |
143 int os::Linux::_page_size = -1; | |
144 bool os::Linux::_is_floating_stack = false; | |
145 bool os::Linux::_is_NPTL = false; | |
146 bool os::Linux::_supports_fast_thread_cpu_time = false; | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
147 const char * os::Linux::_glibc_version = NULL; |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
148 const char * os::Linux::_libpthread_version = NULL; |
0 | 149 |
150 static jlong initial_time_count=0; | |
151 | |
152 static int clock_tics_per_sec = 100; | |
153 | |
154 // For diagnostics to print a message once. see run_periodic_checks | |
155 static sigset_t check_signal_done; | |
156 static bool check_signals = true;; | |
157 | |
158 static pid_t _initial_pid = 0; | |
159 | |
160 /* Signal number used to suspend/resume a thread */ | |
161 | |
162 /* do not use any signal number less than SIGSEGV, see 4355769 */ | |
163 static int SR_signum = SIGUSR2; | |
164 sigset_t SR_sigset; | |
165 | |
242 | 166 /* Used to protect dlsym() calls */ |
167 static pthread_mutex_t dl_mutex; | |
168 | |
3802
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
169 #ifdef JAVASE_EMBEDDED |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
170 class MemNotifyThread: public Thread { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
171 friend class VMStructs; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
172 public: |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
173 virtual void run(); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
174 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
175 private: |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
176 static MemNotifyThread* _memnotify_thread; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
177 int _fd; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
178 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
179 public: |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
180 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
181 // Constructor |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
182 MemNotifyThread(int fd); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
183 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
184 // Tester |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
185 bool is_memnotify_thread() const { return true; } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
186 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
187 // Printing |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
188 char* name() const { return (char*)"Linux MemNotify Thread"; } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
189 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
190 // Returns the single instance of the MemNotifyThread |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
191 static MemNotifyThread* memnotify_thread() { return _memnotify_thread; } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
192 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
193 // Create and start the single instance of MemNotifyThread |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
194 static void start(); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
195 }; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
196 #endif // JAVASE_EMBEDDED |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
197 |
0 | 198 // utility functions |
199 | |
200 static int SR_initialize(); | |
201 static int SR_finalize(); | |
202 | |
203 julong os::available_memory() { | |
204 return Linux::available_memory(); | |
205 } | |
206 | |
207 julong os::Linux::available_memory() { | |
208 // values in struct sysinfo are "unsigned long" | |
209 struct sysinfo si; | |
210 sysinfo(&si); | |
211 | |
212 return (julong)si.freeram * si.mem_unit; | |
213 } | |
214 | |
215 julong os::physical_memory() { | |
216 return Linux::physical_memory(); | |
217 } | |
218 | |
20
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
219 julong os::allocatable_physical_memory(julong size) { |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
220 #ifdef _LP64 |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
221 return size; |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
222 #else |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
223 julong result = MIN2(size, (julong)3800*M); |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
224 if (!is_allocatable(result)) { |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
225 // See comments under solaris for alignment considerations |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
226 julong reasonable_size = (julong)2*G - 2 * os::vm_page_size(); |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
227 result = MIN2(size, reasonable_size); |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
228 } |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
229 return result; |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
230 #endif // _LP64 |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
231 } |
e195fe4c40c7
6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents:
0
diff
changeset
|
232 |
0 | 233 //////////////////////////////////////////////////////////////////////////////// |
234 // environment support | |
235 | |
236 bool os::getenv(const char* name, char* buf, int len) { | |
237 const char* val = ::getenv(name); | |
238 if (val != NULL && strlen(val) < (size_t)len) { | |
239 strcpy(buf, val); | |
240 return true; | |
241 } | |
242 if (len > 0) buf[0] = 0; // return a null string | |
243 return false; | |
244 } | |
245 | |
246 | |
247 // Return true if user is running as root. | |
248 | |
249 bool os::have_special_privileges() { | |
250 static bool init = false; | |
251 static bool privileges = false; | |
252 if (!init) { | |
253 privileges = (getuid() != geteuid()) || (getgid() != getegid()); | |
254 init = true; | |
255 } | |
256 return privileges; | |
257 } | |
258 | |
259 | |
260 #ifndef SYS_gettid | |
261 // i386: 224, ia64: 1105, amd64: 186, sparc 143 | |
262 #ifdef __ia64__ | |
263 #define SYS_gettid 1105 | |
264 #elif __i386__ | |
265 #define SYS_gettid 224 | |
266 #elif __amd64__ | |
267 #define SYS_gettid 186 | |
268 #elif __sparc__ | |
269 #define SYS_gettid 143 | |
270 #else | |
271 #error define gettid for the arch | |
272 #endif | |
273 #endif | |
274 | |
275 // Cpu architecture string | |
1010 | 276 #if defined(ZERO) |
277 static char cpu_arch[] = ZERO_LIBARCH; | |
278 #elif defined(IA64) | |
0 | 279 static char cpu_arch[] = "ia64"; |
280 #elif defined(IA32) | |
281 static char cpu_arch[] = "i386"; | |
282 #elif defined(AMD64) | |
283 static char cpu_arch[] = "amd64"; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
284 #elif defined(ARM) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
285 static char cpu_arch[] = "arm"; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
286 #elif defined(PPC) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
287 static char cpu_arch[] = "ppc"; |
0 | 288 #elif defined(SPARC) |
289 # ifdef _LP64 | |
290 static char cpu_arch[] = "sparcv9"; | |
291 # else | |
292 static char cpu_arch[] = "sparc"; | |
293 # endif | |
294 #else | |
295 #error Add appropriate cpu_arch setting | |
296 #endif | |
297 | |
298 | |
299 // pid_t gettid() | |
300 // | |
301 // Returns the kernel thread id of the currently running thread. Kernel | |
302 // thread id is used to access /proc. | |
303 // | |
304 // (Note that getpid() on LinuxThreads returns kernel thread id too; but | |
305 // on NPTL, it returns the same pid for all threads, as required by POSIX.) | |
306 // | |
307 pid_t os::Linux::gettid() { | |
308 int rslt = syscall(SYS_gettid); | |
309 if (rslt == -1) { | |
310 // old kernel, no NPTL support | |
311 return getpid(); | |
312 } else { | |
313 return (pid_t)rslt; | |
314 } | |
315 } | |
316 | |
317 // Most versions of linux have a bug where the number of processors are | |
318 // determined by looking at the /proc file system. In a chroot environment, | |
319 // the system call returns 1. This causes the VM to act as if it is | |
320 // a single processor and elide locking (see is_MP() call). | |
321 static bool unsafe_chroot_detected = false; | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
322 static const char *unstable_chroot_error = "/proc file system not found.\n" |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
323 "Java may be unstable running multithreaded in a chroot " |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
324 "environment on Linux when /proc filesystem is not mounted."; |
0 | 325 |
326 void os::Linux::initialize_system_info() { | |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
1117
diff
changeset
|
327 set_processor_count(sysconf(_SC_NPROCESSORS_CONF)); |
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
1117
diff
changeset
|
328 if (processor_count() == 1) { |
0 | 329 pid_t pid = os::Linux::gettid(); |
330 char fname[32]; | |
331 jio_snprintf(fname, sizeof(fname), "/proc/%d", pid); | |
332 FILE *fp = fopen(fname, "r"); | |
333 if (fp == NULL) { | |
334 unsafe_chroot_detected = true; | |
335 } else { | |
336 fclose(fp); | |
337 } | |
338 } | |
339 _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE); | |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
1117
diff
changeset
|
340 assert(processor_count() > 0, "linux error"); |
0 | 341 } |
342 | |
343 void os::init_system_properties_values() { | |
344 // char arch[12]; | |
345 // sysinfo(SI_ARCHITECTURE, arch, sizeof(arch)); | |
346 | |
347 // The next steps are taken in the product version: | |
348 // | |
349 // Obtain the JAVA_HOME value from the location of libjvm[_g].so. | |
350 // This library should be located at: | |
351 // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm[_g].so. | |
352 // | |
353 // If "/jre/lib/" appears at the right place in the path, then we | |
354 // assume libjvm[_g].so is installed in a JDK and we use this path. | |
355 // | |
356 // Otherwise exit with message: "Could not create the Java virtual machine." | |
357 // | |
358 // The following extra steps are taken in the debugging version: | |
359 // | |
360 // If "/jre/lib/" does NOT appear at the right place in the path | |
361 // instead of exit check for $JAVA_HOME environment variable. | |
362 // | |
363 // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>, | |
364 // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so | |
365 // it looks like libjvm[_g].so is installed there | |
366 // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm[_g].so. | |
367 // | |
368 // Otherwise exit. | |
369 // | |
370 // Important note: if the location of libjvm.so changes this | |
371 // code needs to be changed accordingly. | |
372 | |
373 // The next few definitions allow the code to be verbatim: | |
374 #define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n)) | |
375 #define getenv(n) ::getenv(n) | |
376 | |
377 /* | |
378 * See ld(1): | |
379 * The linker uses the following search paths to locate required | |
380 * shared libraries: | |
381 * 1: ... | |
382 * ... | |
383 * 7: The default directories, normally /lib and /usr/lib. | |
384 */ | |
509
9656bebe85a7
6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents:
477
diff
changeset
|
385 #if defined(AMD64) || defined(_LP64) && (defined(SPARC) || defined(PPC) || defined(S390)) |
9656bebe85a7
6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents:
477
diff
changeset
|
386 #define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib" |
9656bebe85a7
6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents:
477
diff
changeset
|
387 #else |
0 | 388 #define DEFAULT_LIBPATH "/lib:/usr/lib" |
509
9656bebe85a7
6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents:
477
diff
changeset
|
389 #endif |
0 | 390 |
391 #define EXTENSIONS_DIR "/lib/ext" | |
392 #define ENDORSED_DIR "/lib/endorsed" | |
393 #define REG_DIR "/usr/java/packages" | |
394 | |
395 { | |
396 /* sysclasspath, java_home, dll_dir */ | |
397 { | |
398 char *home_path; | |
399 char *dll_path; | |
400 char *pslash; | |
401 char buf[MAXPATHLEN]; | |
402 os::jvm_path(buf, sizeof(buf)); | |
403 | |
404 // Found the full path to libjvm.so. | |
405 // Now cut the path to <java_home>/jre if we can. | |
406 *(strrchr(buf, '/')) = '\0'; /* get rid of /libjvm.so */ | |
407 pslash = strrchr(buf, '/'); | |
408 if (pslash != NULL) | |
409 *pslash = '\0'; /* get rid of /{client|server|hotspot} */ | |
410 dll_path = malloc(strlen(buf) + 1); | |
411 if (dll_path == NULL) | |
412 return; | |
413 strcpy(dll_path, buf); | |
414 Arguments::set_dll_dir(dll_path); | |
415 | |
416 if (pslash != NULL) { | |
417 pslash = strrchr(buf, '/'); | |
418 if (pslash != NULL) { | |
419 *pslash = '\0'; /* get rid of /<arch> */ | |
420 pslash = strrchr(buf, '/'); | |
421 if (pslash != NULL) | |
422 *pslash = '\0'; /* get rid of /lib */ | |
423 } | |
424 } | |
425 | |
426 home_path = malloc(strlen(buf) + 1); | |
427 if (home_path == NULL) | |
428 return; | |
429 strcpy(home_path, buf); | |
430 Arguments::set_java_home(home_path); | |
431 | |
432 if (!set_boot_path('/', ':')) | |
433 return; | |
434 } | |
435 | |
436 /* | |
437 * Where to look for native libraries | |
438 * | |
439 * Note: Due to a legacy implementation, most of the library path | |
440 * is set in the launcher. This was to accomodate linking restrictions | |
441 * on legacy Linux implementations (which are no longer supported). | |
442 * Eventually, all the library path setting will be done here. | |
443 * | |
444 * However, to prevent the proliferation of improperly built native | |
445 * libraries, the new path component /usr/java/packages is added here. | |
446 * Eventually, all the library path setting will be done here. | |
447 */ | |
448 { | |
449 char *ld_library_path; | |
450 | |
451 /* | |
452 * Construct the invariant part of ld_library_path. Note that the | |
453 * space for the colon and the trailing null are provided by the | |
454 * nulls included by the sizeof operator (so actually we allocate | |
455 * a byte more than necessary). | |
456 */ | |
457 ld_library_path = (char *) malloc(sizeof(REG_DIR) + sizeof("/lib/") + | |
458 strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH)); | |
459 sprintf(ld_library_path, REG_DIR "/lib/%s:" DEFAULT_LIBPATH, cpu_arch); | |
460 | |
461 /* | |
462 * Get the user setting of LD_LIBRARY_PATH, and prepended it. It | |
463 * should always exist (until the legacy problem cited above is | |
464 * addressed). | |
465 */ | |
466 char *v = getenv("LD_LIBRARY_PATH"); | |
467 if (v != NULL) { | |
468 char *t = ld_library_path; | |
469 /* That's +1 for the colon and +1 for the trailing '\0' */ | |
470 ld_library_path = (char *) malloc(strlen(v) + 1 + strlen(t) + 1); | |
471 sprintf(ld_library_path, "%s:%s", v, t); | |
472 } | |
473 Arguments::set_library_path(ld_library_path); | |
474 } | |
475 | |
476 /* | |
477 * Extensions directories. | |
478 * | |
479 * Note that the space for the colon and the trailing null are provided | |
480 * by the nulls included by the sizeof operator (so actually one byte more | |
481 * than necessary is allocated). | |
482 */ | |
483 { | |
484 char *buf = malloc(strlen(Arguments::get_java_home()) + | |
485 sizeof(EXTENSIONS_DIR) + sizeof(REG_DIR) + sizeof(EXTENSIONS_DIR)); | |
486 sprintf(buf, "%s" EXTENSIONS_DIR ":" REG_DIR EXTENSIONS_DIR, | |
487 Arguments::get_java_home()); | |
488 Arguments::set_ext_dirs(buf); | |
489 } | |
490 | |
491 /* Endorsed standards default directory. */ | |
492 { | |
493 char * buf; | |
494 buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR)); | |
495 sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home()); | |
496 Arguments::set_endorsed_dirs(buf); | |
497 } | |
498 } | |
499 | |
500 #undef malloc | |
501 #undef getenv | |
502 #undef EXTENSIONS_DIR | |
503 #undef ENDORSED_DIR | |
504 | |
505 // Done | |
506 return; | |
507 } | |
508 | |
509 //////////////////////////////////////////////////////////////////////////////// | |
510 // breakpoint support | |
511 | |
512 void os::breakpoint() { | |
513 BREAKPOINT; | |
514 } | |
515 | |
516 extern "C" void breakpoint() { | |
517 // use debugger to set breakpoint here | |
518 } | |
519 | |
520 //////////////////////////////////////////////////////////////////////////////// | |
521 // signal support | |
522 | |
523 debug_only(static bool signal_sets_initialized = false); | |
524 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs; | |
525 | |
526 bool os::Linux::is_sig_ignored(int sig) { | |
527 struct sigaction oact; | |
528 sigaction(sig, (struct sigaction*)NULL, &oact); | |
529 void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction) | |
530 : CAST_FROM_FN_PTR(void*, oact.sa_handler); | |
531 if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) | |
532 return true; | |
533 else | |
534 return false; | |
535 } | |
536 | |
537 void os::Linux::signal_sets_init() { | |
538 // Should also have an assertion stating we are still single-threaded. | |
539 assert(!signal_sets_initialized, "Already initialized"); | |
540 // Fill in signals that are necessarily unblocked for all threads in | |
541 // the VM. Currently, we unblock the following signals: | |
542 // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden | |
543 // by -Xrs (=ReduceSignalUsage)); | |
544 // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all | |
545 // other threads. The "ReduceSignalUsage" boolean tells us not to alter | |
546 // the dispositions or masks wrt these signals. | |
547 // Programs embedding the VM that want to use the above signals for their | |
548 // own purposes must, at this time, use the "-Xrs" option to prevent | |
549 // interference with shutdown hooks and BREAK_SIGNAL thread dumping. | |
550 // (See bug 4345157, and other related bugs). | |
551 // In reality, though, unblocking these signals is really a nop, since | |
552 // these signals are not blocked by default. | |
553 sigemptyset(&unblocked_sigs); | |
554 sigemptyset(&allowdebug_blocked_sigs); | |
555 sigaddset(&unblocked_sigs, SIGILL); | |
556 sigaddset(&unblocked_sigs, SIGSEGV); | |
557 sigaddset(&unblocked_sigs, SIGBUS); | |
558 sigaddset(&unblocked_sigs, SIGFPE); | |
559 sigaddset(&unblocked_sigs, SR_signum); | |
560 | |
561 if (!ReduceSignalUsage) { | |
562 if (!os::Linux::is_sig_ignored(SHUTDOWN1_SIGNAL)) { | |
563 sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL); | |
564 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL); | |
565 } | |
566 if (!os::Linux::is_sig_ignored(SHUTDOWN2_SIGNAL)) { | |
567 sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL); | |
568 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL); | |
569 } | |
570 if (!os::Linux::is_sig_ignored(SHUTDOWN3_SIGNAL)) { | |
571 sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL); | |
572 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL); | |
573 } | |
574 } | |
575 // Fill in signals that are blocked by all but the VM thread. | |
576 sigemptyset(&vm_sigs); | |
577 if (!ReduceSignalUsage) | |
578 sigaddset(&vm_sigs, BREAK_SIGNAL); | |
579 debug_only(signal_sets_initialized = true); | |
580 | |
581 } | |
582 | |
583 // These are signals that are unblocked while a thread is running Java. | |
584 // (For some reason, they get blocked by default.) | |
585 sigset_t* os::Linux::unblocked_signals() { | |
586 assert(signal_sets_initialized, "Not initialized"); | |
587 return &unblocked_sigs; | |
588 } | |
589 | |
590 // These are the signals that are blocked while a (non-VM) thread is | |
591 // running Java. Only the VM thread handles these signals. | |
592 sigset_t* os::Linux::vm_signals() { | |
593 assert(signal_sets_initialized, "Not initialized"); | |
594 return &vm_sigs; | |
595 } | |
596 | |
597 // These are signals that are blocked during cond_wait to allow debugger in | |
598 sigset_t* os::Linux::allowdebug_blocked_signals() { | |
599 assert(signal_sets_initialized, "Not initialized"); | |
600 return &allowdebug_blocked_sigs; | |
601 } | |
602 | |
603 void os::Linux::hotspot_sigmask(Thread* thread) { | |
604 | |
605 //Save caller's signal mask before setting VM signal mask | |
606 sigset_t caller_sigmask; | |
607 pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask); | |
608 | |
609 OSThread* osthread = thread->osthread(); | |
610 osthread->set_caller_sigmask(caller_sigmask); | |
611 | |
612 pthread_sigmask(SIG_UNBLOCK, os::Linux::unblocked_signals(), NULL); | |
613 | |
614 if (!ReduceSignalUsage) { | |
615 if (thread->is_VM_thread()) { | |
616 // Only the VM thread handles BREAK_SIGNAL ... | |
617 pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL); | |
618 } else { | |
619 // ... all other threads block BREAK_SIGNAL | |
620 pthread_sigmask(SIG_BLOCK, vm_signals(), NULL); | |
621 } | |
622 } | |
623 } | |
624 | |
625 ////////////////////////////////////////////////////////////////////////////// | |
626 // detecting pthread library | |
627 | |
628 void os::Linux::libpthread_init() { | |
629 // Save glibc and pthread version strings. Note that _CS_GNU_LIBC_VERSION | |
630 // and _CS_GNU_LIBPTHREAD_VERSION are supported in glibc >= 2.3.2. Use a | |
631 // generic name for earlier versions. | |
632 // Define macros here so we can build HotSpot on old systems. | |
633 # ifndef _CS_GNU_LIBC_VERSION | |
634 # define _CS_GNU_LIBC_VERSION 2 | |
635 # endif | |
636 # ifndef _CS_GNU_LIBPTHREAD_VERSION | |
637 # define _CS_GNU_LIBPTHREAD_VERSION 3 | |
638 # endif | |
639 | |
640 size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0); | |
641 if (n > 0) { | |
642 char *str = (char *)malloc(n); | |
643 confstr(_CS_GNU_LIBC_VERSION, str, n); | |
644 os::Linux::set_glibc_version(str); | |
645 } else { | |
646 // _CS_GNU_LIBC_VERSION is not supported, try gnu_get_libc_version() | |
647 static char _gnu_libc_version[32]; | |
648 jio_snprintf(_gnu_libc_version, sizeof(_gnu_libc_version), | |
649 "glibc %s %s", gnu_get_libc_version(), gnu_get_libc_release()); | |
650 os::Linux::set_glibc_version(_gnu_libc_version); | |
651 } | |
652 | |
653 n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0); | |
654 if (n > 0) { | |
655 char *str = (char *)malloc(n); | |
656 confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n); | |
657 // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells | |
658 // us "NPTL-0.29" even we are running with LinuxThreads. Check if this | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
659 // is the case. LinuxThreads has a hard limit on max number of threads. |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
660 // So sysconf(_SC_THREAD_THREADS_MAX) will return a positive value. |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
661 // On the other hand, NPTL does not have such a limit, sysconf() |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
662 // will return -1 and errno is not changed. Check if it is really NPTL. |
0 | 663 if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 && |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
664 strstr(str, "NPTL") && |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
665 sysconf(_SC_THREAD_THREADS_MAX) > 0) { |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
666 free(str); |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
667 os::Linux::set_libpthread_version("linuxthreads"); |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
668 } else { |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
669 os::Linux::set_libpthread_version(str); |
0 | 670 } |
671 } else { | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
672 // glibc before 2.3.2 only has LinuxThreads. |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
673 os::Linux::set_libpthread_version("linuxthreads"); |
0 | 674 } |
675 | |
676 if (strstr(libpthread_version(), "NPTL")) { | |
677 os::Linux::set_is_NPTL(); | |
678 } else { | |
679 os::Linux::set_is_LinuxThreads(); | |
680 } | |
681 | |
682 // LinuxThreads have two flavors: floating-stack mode, which allows variable | |
683 // stack size; and fixed-stack mode. NPTL is always floating-stack. | |
684 if (os::Linux::is_NPTL() || os::Linux::supports_variable_stack_size()) { | |
685 os::Linux::set_is_floating_stack(); | |
686 } | |
687 } | |
688 | |
689 ///////////////////////////////////////////////////////////////////////////// | |
690 // thread stack | |
691 | |
692 // Force Linux kernel to expand current thread stack. If "bottom" is close | |
693 // to the stack guard, caller should block all signals. | |
694 // | |
695 // MAP_GROWSDOWN: | |
696 // A special mmap() flag that is used to implement thread stacks. It tells | |
697 // kernel that the memory region should extend downwards when needed. This | |
698 // allows early versions of LinuxThreads to only mmap the first few pages | |
699 // when creating a new thread. Linux kernel will automatically expand thread | |
700 // stack as needed (on page faults). | |
701 // | |
702 // However, because the memory region of a MAP_GROWSDOWN stack can grow on | |
703 // demand, if a page fault happens outside an already mapped MAP_GROWSDOWN | |
704 // region, it's hard to tell if the fault is due to a legitimate stack | |
705 // access or because of reading/writing non-exist memory (e.g. buffer | |
706 // overrun). As a rule, if the fault happens below current stack pointer, | |
707 // Linux kernel does not expand stack, instead a SIGSEGV is sent to the | |
708 // application (see Linux kernel fault.c). | |
709 // | |
710 // This Linux feature can cause SIGSEGV when VM bangs thread stack for | |
711 // stack overflow detection. | |
712 // | |
713 // Newer version of LinuxThreads (since glibc-2.2, or, RH-7.x) and NPTL do | |
714 // not use this flag. However, the stack of initial thread is not created | |
715 // by pthread, it is still MAP_GROWSDOWN. Also it's possible (though | |
716 // unlikely) that user code can create a thread with MAP_GROWSDOWN stack | |
717 // and then attach the thread to JVM. | |
718 // | |
719 // To get around the problem and allow stack banging on Linux, we need to | |
720 // manually expand thread stack after receiving the SIGSEGV. | |
721 // | |
722 // There are two ways to expand thread stack to address "bottom", we used | |
723 // both of them in JVM before 1.5: | |
724 // 1. adjust stack pointer first so that it is below "bottom", and then | |
725 // touch "bottom" | |
726 // 2. mmap() the page in question | |
727 // | |
728 // Now alternate signal stack is gone, it's harder to use 2. For instance, | |
729 // if current sp is already near the lower end of page 101, and we need to | |
730 // call mmap() to map page 100, it is possible that part of the mmap() frame | |
731 // will be placed in page 100. When page 100 is mapped, it is zero-filled. | |
732 // That will destroy the mmap() frame and cause VM to crash. | |
733 // | |
734 // The following code works by adjusting sp first, then accessing the "bottom" | |
735 // page to force a page fault. Linux kernel will then automatically expand the | |
736 // stack mapping. | |
737 // | |
738 // _expand_stack_to() assumes its frame size is less than page size, which | |
739 // should always be true if the function is not inlined. | |
740 | |
741 #if __GNUC__ < 3 // gcc 2.x does not support noinline attribute | |
742 #define NOINLINE | |
743 #else | |
744 #define NOINLINE __attribute__ ((noinline)) | |
745 #endif | |
746 | |
747 static void _expand_stack_to(address bottom) NOINLINE; | |
748 | |
749 static void _expand_stack_to(address bottom) { | |
750 address sp; | |
751 size_t size; | |
752 volatile char *p; | |
753 | |
754 // Adjust bottom to point to the largest address within the same page, it | |
755 // gives us a one-page buffer if alloca() allocates slightly more memory. | |
756 bottom = (address)align_size_down((uintptr_t)bottom, os::Linux::page_size()); | |
757 bottom += os::Linux::page_size() - 1; | |
758 | |
759 // sp might be slightly above current stack pointer; if that's the case, we | |
760 // will alloca() a little more space than necessary, which is OK. Don't use | |
761 // os::current_stack_pointer(), as its result can be slightly below current | |
762 // stack pointer, causing us to not alloca enough to reach "bottom". | |
763 sp = (address)&sp; | |
764 | |
765 if (sp > bottom) { | |
766 size = sp - bottom; | |
767 p = (volatile char *)alloca(size); | |
768 assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?"); | |
769 p[0] = '\0'; | |
770 } | |
771 } | |
772 | |
773 bool os::Linux::manually_expand_stack(JavaThread * t, address addr) { | |
774 assert(t!=NULL, "just checking"); | |
775 assert(t->osthread()->expanding_stack(), "expand should be set"); | |
776 assert(t->stack_base() != NULL, "stack_base was not initialized"); | |
777 | |
778 if (addr < t->stack_base() && addr >= t->stack_yellow_zone_base()) { | |
779 sigset_t mask_all, old_sigset; | |
780 sigfillset(&mask_all); | |
781 pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset); | |
782 _expand_stack_to(addr); | |
783 pthread_sigmask(SIG_SETMASK, &old_sigset, NULL); | |
784 return true; | |
785 } | |
786 return false; | |
787 } | |
788 | |
789 ////////////////////////////////////////////////////////////////////////////// | |
790 // create new thread | |
791 | |
792 static address highest_vm_reserved_address(); | |
793 | |
794 // check if it's safe to start a new thread | |
795 static bool _thread_safety_check(Thread* thread) { | |
796 if (os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack()) { | |
797 // Fixed stack LinuxThreads (SuSE Linux/x86, and some versions of Redhat) | |
798 // Heap is mmap'ed at lower end of memory space. Thread stacks are | |
799 // allocated (MAP_FIXED) from high address space. Every thread stack | |
800 // occupies a fixed size slot (usually 2Mbytes, but user can change | |
801 // it to other values if they rebuild LinuxThreads). | |
802 // | |
803 // Problem with MAP_FIXED is that mmap() can still succeed even part of | |
804 // the memory region has already been mmap'ed. That means if we have too | |
805 // many threads and/or very large heap, eventually thread stack will | |
806 // collide with heap. | |
807 // | |
808 // Here we try to prevent heap/stack collision by comparing current | |
809 // stack bottom with the highest address that has been mmap'ed by JVM | |
810 // plus a safety margin for memory maps created by native code. | |
811 // | |
812 // This feature can be disabled by setting ThreadSafetyMargin to 0 | |
813 // | |
814 if (ThreadSafetyMargin > 0) { | |
815 address stack_bottom = os::current_stack_base() - os::current_stack_size(); | |
816 | |
817 // not safe if our stack extends below the safety margin | |
818 return stack_bottom - ThreadSafetyMargin >= highest_vm_reserved_address(); | |
819 } else { | |
820 return true; | |
821 } | |
822 } else { | |
823 // Floating stack LinuxThreads or NPTL: | |
824 // Unlike fixed stack LinuxThreads, thread stacks are not MAP_FIXED. When | |
825 // there's not enough space left, pthread_create() will fail. If we come | |
826 // here, that means enough space has been reserved for stack. | |
827 return true; | |
828 } | |
829 } | |
830 | |
831 // Thread start routine for all newly created threads | |
832 static void *java_start(Thread *thread) { | |
833 // Try to randomize the cache line index of hot stack frames. | |
834 // This helps when threads of the same stack traces evict each other's | |
835 // cache lines. The threads can be either from the same JVM instance, or | |
836 // from different JVM instances. The benefit is especially true for | |
837 // processors with hyperthreading technology. | |
838 static int counter = 0; | |
839 int pid = os::current_process_id(); | |
840 alloca(((pid ^ counter++) & 7) * 128); | |
841 | |
842 ThreadLocalStorage::set_thread(thread); | |
843 | |
844 OSThread* osthread = thread->osthread(); | |
845 Monitor* sync = osthread->startThread_lock(); | |
846 | |
847 // non floating stack LinuxThreads needs extra check, see above | |
848 if (!_thread_safety_check(thread)) { | |
849 // notify parent thread | |
850 MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); | |
851 osthread->set_state(ZOMBIE); | |
852 sync->notify_all(); | |
853 return NULL; | |
854 } | |
855 | |
856 // thread_id is kernel thread id (similar to Solaris LWP id) | |
857 osthread->set_thread_id(os::Linux::gettid()); | |
858 | |
859 if (UseNUMA) { | |
860 int lgrp_id = os::numa_get_group_id(); | |
861 if (lgrp_id != -1) { | |
862 thread->set_lgrp_id(lgrp_id); | |
863 } | |
864 } | |
865 // initialize signal mask for this thread | |
866 os::Linux::hotspot_sigmask(thread); | |
867 | |
868 // initialize floating point control register | |
869 os::Linux::init_thread_fpu_state(); | |
870 | |
871 // handshaking with parent thread | |
872 { | |
873 MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); | |
874 | |
875 // notify parent thread | |
876 osthread->set_state(INITIALIZED); | |
877 sync->notify_all(); | |
878 | |
879 // wait until os::start_thread() | |
880 while (osthread->get_state() == INITIALIZED) { | |
881 sync->wait(Mutex::_no_safepoint_check_flag); | |
882 } | |
883 } | |
884 | |
885 // call one more level start routine | |
886 thread->run(); | |
887 | |
888 return 0; | |
889 } | |
890 | |
891 bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { | |
892 assert(thread->osthread() == NULL, "caller responsible"); | |
893 | |
894 // Allocate the OSThread object | |
895 OSThread* osthread = new OSThread(NULL, NULL); | |
896 if (osthread == NULL) { | |
897 return false; | |
898 } | |
899 | |
900 // set the correct thread state | |
901 osthread->set_thread_type(thr_type); | |
902 | |
903 // Initial state is ALLOCATED but not INITIALIZED | |
904 osthread->set_state(ALLOCATED); | |
905 | |
906 thread->set_osthread(osthread); | |
907 | |
908 // init thread attributes | |
909 pthread_attr_t attr; | |
910 pthread_attr_init(&attr); | |
911 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
912 | |
913 // stack size | |
914 if (os::Linux::supports_variable_stack_size()) { | |
915 // calculate stack size if it's not specified by caller | |
916 if (stack_size == 0) { | |
917 stack_size = os::Linux::default_stack_size(thr_type); | |
918 | |
919 switch (thr_type) { | |
920 case os::java_thread: | |
1867
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
921 // Java threads use ThreadStackSize which default value can be |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
922 // changed with the flag -Xss |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
923 assert (JavaThread::stack_size_at_create() > 0, "this should be set"); |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
924 stack_size = JavaThread::stack_size_at_create(); |
0 | 925 break; |
926 case os::compiler_thread: | |
927 if (CompilerThreadStackSize > 0) { | |
928 stack_size = (size_t)(CompilerThreadStackSize * K); | |
929 break; | |
930 } // else fall through: | |
931 // use VMThreadStackSize if CompilerThreadStackSize is not defined | |
932 case os::vm_thread: | |
933 case os::pgc_thread: | |
934 case os::cgc_thread: | |
935 case os::watcher_thread: | |
936 if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K); | |
937 break; | |
938 } | |
939 } | |
940 | |
941 stack_size = MAX2(stack_size, os::Linux::min_stack_allowed); | |
942 pthread_attr_setstacksize(&attr, stack_size); | |
943 } else { | |
944 // let pthread_create() pick the default value. | |
945 } | |
946 | |
947 // glibc guard page | |
948 pthread_attr_setguardsize(&attr, os::Linux::default_guard_size(thr_type)); | |
949 | |
950 ThreadState state; | |
951 | |
952 { | |
953 // Serialize thread creation if we are running with fixed stack LinuxThreads | |
954 bool lock = os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack(); | |
955 if (lock) { | |
956 os::Linux::createThread_lock()->lock_without_safepoint_check(); | |
957 } | |
958 | |
959 pthread_t tid; | |
960 int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); | |
961 | |
962 pthread_attr_destroy(&attr); | |
963 | |
964 if (ret != 0) { | |
965 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
966 perror("pthread_create()"); | |
967 } | |
968 // Need to clean up stuff we've allocated so far | |
969 thread->set_osthread(NULL); | |
970 delete osthread; | |
971 if (lock) os::Linux::createThread_lock()->unlock(); | |
972 return false; | |
973 } | |
974 | |
975 // Store pthread info into the OSThread | |
976 osthread->set_pthread_id(tid); | |
977 | |
978 // Wait until child thread is either initialized or aborted | |
979 { | |
980 Monitor* sync_with_child = osthread->startThread_lock(); | |
981 MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag); | |
982 while ((state = osthread->get_state()) == ALLOCATED) { | |
983 sync_with_child->wait(Mutex::_no_safepoint_check_flag); | |
984 } | |
985 } | |
986 | |
987 if (lock) { | |
988 os::Linux::createThread_lock()->unlock(); | |
989 } | |
990 } | |
991 | |
992 // Aborted due to thread limit being reached | |
993 if (state == ZOMBIE) { | |
994 thread->set_osthread(NULL); | |
995 delete osthread; | |
996 return false; | |
997 } | |
998 | |
999 // The thread is returned suspended (in state INITIALIZED), | |
1000 // and is started higher up in the call chain | |
1001 assert(state == INITIALIZED, "race condition"); | |
1002 return true; | |
1003 } | |
1004 | |
1005 ///////////////////////////////////////////////////////////////////////////// | |
1006 // attach existing thread | |
1007 | |
1008 // bootstrap the main thread | |
1009 bool os::create_main_thread(JavaThread* thread) { | |
1010 assert(os::Linux::_main_thread == pthread_self(), "should be called inside main thread"); | |
1011 return create_attached_thread(thread); | |
1012 } | |
1013 | |
1014 bool os::create_attached_thread(JavaThread* thread) { | |
1015 #ifdef ASSERT | |
1016 thread->verify_not_published(); | |
1017 #endif | |
1018 | |
1019 // Allocate the OSThread object | |
1020 OSThread* osthread = new OSThread(NULL, NULL); | |
1021 | |
1022 if (osthread == NULL) { | |
1023 return false; | |
1024 } | |
1025 | |
1026 // Store pthread info into the OSThread | |
1027 osthread->set_thread_id(os::Linux::gettid()); | |
1028 osthread->set_pthread_id(::pthread_self()); | |
1029 | |
1030 // initialize floating point control register | |
1031 os::Linux::init_thread_fpu_state(); | |
1032 | |
1033 // Initial thread state is RUNNABLE | |
1034 osthread->set_state(RUNNABLE); | |
1035 | |
1036 thread->set_osthread(osthread); | |
1037 | |
1038 if (UseNUMA) { | |
1039 int lgrp_id = os::numa_get_group_id(); | |
1040 if (lgrp_id != -1) { | |
1041 thread->set_lgrp_id(lgrp_id); | |
1042 } | |
1043 } | |
1044 | |
1045 if (os::Linux::is_initial_thread()) { | |
1046 // If current thread is initial thread, its stack is mapped on demand, | |
1047 // see notes about MAP_GROWSDOWN. Here we try to force kernel to map | |
1048 // the entire stack region to avoid SEGV in stack banging. | |
1049 // It is also useful to get around the heap-stack-gap problem on SuSE | |
1050 // kernel (see 4821821 for details). We first expand stack to the top | |
1051 // of yellow zone, then enable stack yellow zone (order is significant, | |
1052 // enabling yellow zone first will crash JVM on SuSE Linux), so there | |
1053 // is no gap between the last two virtual memory regions. | |
1054 | |
1055 JavaThread *jt = (JavaThread *)thread; | |
1056 address addr = jt->stack_yellow_zone_base(); | |
1057 assert(addr != NULL, "initialization problem?"); | |
1058 assert(jt->stack_available(addr) > 0, "stack guard should not be enabled"); | |
1059 | |
1060 osthread->set_expanding_stack(); | |
1061 os::Linux::manually_expand_stack(jt, addr); | |
1062 osthread->clear_expanding_stack(); | |
1063 } | |
1064 | |
1065 // initialize signal mask for this thread | |
1066 // and save the caller's signal mask | |
1067 os::Linux::hotspot_sigmask(thread); | |
1068 | |
1069 return true; | |
1070 } | |
1071 | |
1072 void os::pd_start_thread(Thread* thread) { | |
1073 OSThread * osthread = thread->osthread(); | |
1074 assert(osthread->get_state() != INITIALIZED, "just checking"); | |
1075 Monitor* sync_with_child = osthread->startThread_lock(); | |
1076 MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag); | |
1077 sync_with_child->notify(); | |
1078 } | |
1079 | |
1080 // Free Linux resources related to the OSThread | |
1081 void os::free_thread(OSThread* osthread) { | |
1082 assert(osthread != NULL, "osthread not set"); | |
1083 | |
1084 if (Thread::current()->osthread() == osthread) { | |
1085 // Restore caller's signal mask | |
1086 sigset_t sigmask = osthread->caller_sigmask(); | |
1087 pthread_sigmask(SIG_SETMASK, &sigmask, NULL); | |
1088 } | |
1089 | |
1090 delete osthread; | |
1091 } | |
1092 | |
1093 ////////////////////////////////////////////////////////////////////////////// | |
1094 // thread local storage | |
1095 | |
1096 int os::allocate_thread_local_storage() { | |
1097 pthread_key_t key; | |
1098 int rslt = pthread_key_create(&key, NULL); | |
1099 assert(rslt == 0, "cannot allocate thread local storage"); | |
1100 return (int)key; | |
1101 } | |
1102 | |
1103 // Note: This is currently not used by VM, as we don't destroy TLS key | |
1104 // on VM exit. | |
1105 void os::free_thread_local_storage(int index) { | |
1106 int rslt = pthread_key_delete((pthread_key_t)index); | |
1107 assert(rslt == 0, "invalid index"); | |
1108 } | |
1109 | |
1110 void os::thread_local_storage_at_put(int index, void* value) { | |
1111 int rslt = pthread_setspecific((pthread_key_t)index, value); | |
1112 assert(rslt == 0, "pthread_setspecific failed"); | |
1113 } | |
1114 | |
1115 extern "C" Thread* get_thread() { | |
1116 return ThreadLocalStorage::thread(); | |
1117 } | |
1118 | |
1119 ////////////////////////////////////////////////////////////////////////////// | |
1120 // initial thread | |
1121 | |
1122 // Check if current thread is the initial thread, similar to Solaris thr_main. | |
1123 bool os::Linux::is_initial_thread(void) { | |
1124 char dummy; | |
1125 // If called before init complete, thread stack bottom will be null. | |
1126 // Can be called if fatal error occurs before initialization. | |
1127 if (initial_thread_stack_bottom() == NULL) return false; | |
1128 assert(initial_thread_stack_bottom() != NULL && | |
1129 initial_thread_stack_size() != 0, | |
1130 "os::init did not locate initial thread's stack region"); | |
1131 if ((address)&dummy >= initial_thread_stack_bottom() && | |
1132 (address)&dummy < initial_thread_stack_bottom() + initial_thread_stack_size()) | |
1133 return true; | |
1134 else return false; | |
1135 } | |
1136 | |
1137 // Find the virtual memory area that contains addr | |
1138 static bool find_vma(address addr, address* vma_low, address* vma_high) { | |
1139 FILE *fp = fopen("/proc/self/maps", "r"); | |
1140 if (fp) { | |
1141 address low, high; | |
1142 while (!feof(fp)) { | |
1143 if (fscanf(fp, "%p-%p", &low, &high) == 2) { | |
1144 if (low <= addr && addr < high) { | |
1145 if (vma_low) *vma_low = low; | |
1146 if (vma_high) *vma_high = high; | |
1147 fclose (fp); | |
1148 return true; | |
1149 } | |
1150 } | |
1151 for (;;) { | |
1152 int ch = fgetc(fp); | |
1153 if (ch == EOF || ch == (int)'\n') break; | |
1154 } | |
1155 } | |
1156 fclose(fp); | |
1157 } | |
1158 return false; | |
1159 } | |
1160 | |
1161 // Locate initial thread stack. This special handling of initial thread stack | |
1162 // is needed because pthread_getattr_np() on most (all?) Linux distros returns | |
1163 // bogus value for initial thread. | |
1164 void os::Linux::capture_initial_stack(size_t max_size) { | |
1165 // stack size is the easy part, get it from RLIMIT_STACK | |
1166 size_t stack_size; | |
1167 struct rlimit rlim; | |
1168 getrlimit(RLIMIT_STACK, &rlim); | |
1169 stack_size = rlim.rlim_cur; | |
1170 | |
1171 // 6308388: a bug in ld.so will relocate its own .data section to the | |
1172 // lower end of primordial stack; reduce ulimit -s value a little bit | |
1173 // so we won't install guard page on ld.so's data section. | |
1174 stack_size -= 2 * page_size(); | |
1175 | |
1176 // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat | |
1177 // 7.1, in both cases we will get 2G in return value. | |
1178 // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0, | |
1179 // SuSE 7.2, Debian) can not handle alternate signal stack correctly | |
1180 // for initial thread if its stack size exceeds 6M. Cap it at 2M, | |
1181 // in case other parts in glibc still assumes 2M max stack size. | |
1182 // FIXME: alt signal stack is gone, maybe we can relax this constraint? | |
1183 #ifndef IA64 | |
1184 if (stack_size > 2 * K * K) stack_size = 2 * K * K; | |
1185 #else | |
1186 // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small | |
1187 if (stack_size > 4 * K * K) stack_size = 4 * K * K; | |
1188 #endif | |
1189 | |
1190 // Try to figure out where the stack base (top) is. This is harder. | |
1191 // | |
1192 // When an application is started, glibc saves the initial stack pointer in | |
1193 // a global variable "__libc_stack_end", which is then used by system | |
1194 // libraries. __libc_stack_end should be pretty close to stack top. The | |
1195 // variable is available since the very early days. However, because it is | |
1196 // a private interface, it could disappear in the future. | |
1197 // | |
1198 // Linux kernel saves start_stack information in /proc/<pid>/stat. Similar | |
1199 // to __libc_stack_end, it is very close to stack top, but isn't the real | |
1200 // stack top. Note that /proc may not exist if VM is running as a chroot | |
1201 // program, so reading /proc/<pid>/stat could fail. Also the contents of | |
1202 // /proc/<pid>/stat could change in the future (though unlikely). | |
1203 // | |
1204 // We try __libc_stack_end first. If that doesn't work, look for | |
1205 // /proc/<pid>/stat. If neither of them works, we use current stack pointer | |
1206 // as a hint, which should work well in most cases. | |
1207 | |
1208 uintptr_t stack_start; | |
1209 | |
1210 // try __libc_stack_end first | |
1211 uintptr_t *p = (uintptr_t *)dlsym(RTLD_DEFAULT, "__libc_stack_end"); | |
1212 if (p && *p) { | |
1213 stack_start = *p; | |
1214 } else { | |
1215 // see if we can get the start_stack field from /proc/self/stat | |
1216 FILE *fp; | |
1217 int pid; | |
1218 char state; | |
1219 int ppid; | |
1220 int pgrp; | |
1221 int session; | |
1222 int nr; | |
1223 int tpgrp; | |
1224 unsigned long flags; | |
1225 unsigned long minflt; | |
1226 unsigned long cminflt; | |
1227 unsigned long majflt; | |
1228 unsigned long cmajflt; | |
1229 unsigned long utime; | |
1230 unsigned long stime; | |
1231 long cutime; | |
1232 long cstime; | |
1233 long prio; | |
1234 long nice; | |
1235 long junk; | |
1236 long it_real; | |
1237 uintptr_t start; | |
1238 uintptr_t vsize; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1239 intptr_t rss; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1240 uintptr_t rsslim; |
0 | 1241 uintptr_t scodes; |
1242 uintptr_t ecode; | |
1243 int i; | |
1244 | |
1245 // Figure what the primordial thread stack base is. Code is inspired | |
1246 // by email from Hans Boehm. /proc/self/stat begins with current pid, | |
1247 // followed by command name surrounded by parentheses, state, etc. | |
1248 char stat[2048]; | |
1249 int statlen; | |
1250 | |
1251 fp = fopen("/proc/self/stat", "r"); | |
1252 if (fp) { | |
1253 statlen = fread(stat, 1, 2047, fp); | |
1254 stat[statlen] = '\0'; | |
1255 fclose(fp); | |
1256 | |
1257 // Skip pid and the command string. Note that we could be dealing with | |
1258 // weird command names, e.g. user could decide to rename java launcher | |
1259 // to "java 1.4.2 :)", then the stat file would look like | |
1260 // 1234 (java 1.4.2 :)) R ... ... | |
1261 // We don't really need to know the command string, just find the last | |
1262 // occurrence of ")" and then start parsing from there. See bug 4726580. | |
1263 char * s = strrchr(stat, ')'); | |
1264 | |
1265 i = 0; | |
1266 if (s) { | |
1267 // Skip blank chars | |
1268 do s++; while (isspace(*s)); | |
1269 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1270 #define _UFM UINTX_FORMAT |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1271 #define _DFM INTX_FORMAT |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1272 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1273 /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1274 /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1275 i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM, |
0 | 1276 &state, /* 3 %c */ |
1277 &ppid, /* 4 %d */ | |
1278 &pgrp, /* 5 %d */ | |
1279 &session, /* 6 %d */ | |
1280 &nr, /* 7 %d */ | |
1281 &tpgrp, /* 8 %d */ | |
1282 &flags, /* 9 %lu */ | |
1283 &minflt, /* 10 %lu */ | |
1284 &cminflt, /* 11 %lu */ | |
1285 &majflt, /* 12 %lu */ | |
1286 &cmajflt, /* 13 %lu */ | |
1287 &utime, /* 14 %lu */ | |
1288 &stime, /* 15 %lu */ | |
1289 &cutime, /* 16 %ld */ | |
1290 &cstime, /* 17 %ld */ | |
1291 &prio, /* 18 %ld */ | |
1292 &nice, /* 19 %ld */ | |
1293 &junk, /* 20 %ld */ | |
1294 &it_real, /* 21 %ld */ | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1295 &start, /* 22 UINTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1296 &vsize, /* 23 UINTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1297 &rss, /* 24 INTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1298 &rsslim, /* 25 UINTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1299 &scodes, /* 26 UINTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1300 &ecode, /* 27 UINTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1301 &stack_start); /* 28 UINTX_FORMAT */ |
0 | 1302 } |
1303 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1304 #undef _UFM |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1305 #undef _DFM |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1306 |
0 | 1307 if (i != 28 - 2) { |
1308 assert(false, "Bad conversion from /proc/self/stat"); | |
1309 // product mode - assume we are the initial thread, good luck in the | |
1310 // embedded case. | |
1311 warning("Can't detect initial thread stack location - bad conversion"); | |
1312 stack_start = (uintptr_t) &rlim; | |
1313 } | |
1314 } else { | |
1315 // For some reason we can't open /proc/self/stat (for example, running on | |
1316 // FreeBSD with a Linux emulator, or inside chroot), this should work for | |
1317 // most cases, so don't abort: | |
1318 warning("Can't detect initial thread stack location - no /proc/self/stat"); | |
1319 stack_start = (uintptr_t) &rlim; | |
1320 } | |
1321 } | |
1322 | |
1323 // Now we have a pointer (stack_start) very close to the stack top, the | |
1324 // next thing to do is to figure out the exact location of stack top. We | |
1325 // can find out the virtual memory area that contains stack_start by | |
1326 // reading /proc/self/maps, it should be the last vma in /proc/self/maps, | |
1327 // and its upper limit is the real stack top. (again, this would fail if | |
1328 // running inside chroot, because /proc may not exist.) | |
1329 | |
1330 uintptr_t stack_top; | |
1331 address low, high; | |
1332 if (find_vma((address)stack_start, &low, &high)) { | |
1333 // success, "high" is the true stack top. (ignore "low", because initial | |
1334 // thread stack grows on demand, its real bottom is high - RLIMIT_STACK.) | |
1335 stack_top = (uintptr_t)high; | |
1336 } else { | |
1337 // failed, likely because /proc/self/maps does not exist | |
1338 warning("Can't detect initial thread stack location - find_vma failed"); | |
1339 // best effort: stack_start is normally within a few pages below the real | |
1340 // stack top, use it as stack top, and reduce stack size so we won't put | |
1341 // guard page outside stack. | |
1342 stack_top = stack_start; | |
1343 stack_size -= 16 * page_size(); | |
1344 } | |
1345 | |
1346 // stack_top could be partially down the page so align it | |
1347 stack_top = align_size_up(stack_top, page_size()); | |
1348 | |
1349 if (max_size && stack_size > max_size) { | |
1350 _initial_thread_stack_size = max_size; | |
1351 } else { | |
1352 _initial_thread_stack_size = stack_size; | |
1353 } | |
1354 | |
1355 _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size()); | |
1356 _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size; | |
1357 } | |
1358 | |
1359 //////////////////////////////////////////////////////////////////////////////// | |
1360 // time support | |
1361 | |
1362 // Time since start-up in seconds to a fine granularity. | |
1363 // Used by VMSelfDestructTimer and the MemProfiler. | |
1364 double os::elapsedTime() { | |
1365 | |
1366 return (double)(os::elapsed_counter()) * 0.000001; | |
1367 } | |
1368 | |
1369 jlong os::elapsed_counter() { | |
1370 timeval time; | |
1371 int status = gettimeofday(&time, NULL); | |
1372 return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count; | |
1373 } | |
1374 | |
1375 jlong os::elapsed_frequency() { | |
1376 return (1000 * 1000); | |
1377 } | |
1378 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1379 // For now, we say that linux does not support vtime. I have no idea |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1380 // whether it can actually be made to (DLD, 9/13/05). |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1381 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1382 bool os::supports_vtime() { return false; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1383 bool os::enable_vtime() { return false; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1384 bool os::vtime_enabled() { return false; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1385 double os::elapsedVTime() { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1386 // better than nothing, but not much |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1387 return elapsedTime(); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1388 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1389 |
61 | 1390 jlong os::javaTimeMillis() { |
0 | 1391 timeval time; |
1392 int status = gettimeofday(&time, NULL); | |
1393 assert(status != -1, "linux error"); | |
1394 return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); | |
1395 } | |
1396 | |
1397 #ifndef CLOCK_MONOTONIC | |
1398 #define CLOCK_MONOTONIC (1) | |
1399 #endif | |
1400 | |
1401 void os::Linux::clock_init() { | |
1402 // we do dlopen's in this particular order due to bug in linux | |
1403 // dynamical loader (see 6348968) leading to crash on exit | |
1404 void* handle = dlopen("librt.so.1", RTLD_LAZY); | |
1405 if (handle == NULL) { | |
1406 handle = dlopen("librt.so", RTLD_LAZY); | |
1407 } | |
1408 | |
1409 if (handle) { | |
1410 int (*clock_getres_func)(clockid_t, struct timespec*) = | |
1411 (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres"); | |
1412 int (*clock_gettime_func)(clockid_t, struct timespec*) = | |
1413 (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_gettime"); | |
1414 if (clock_getres_func && clock_gettime_func) { | |
1415 // See if monotonic clock is supported by the kernel. Note that some | |
1416 // early implementations simply return kernel jiffies (updated every | |
1417 // 1/100 or 1/1000 second). It would be bad to use such a low res clock | |
1418 // for nano time (though the monotonic property is still nice to have). | |
1419 // It's fixed in newer kernels, however clock_getres() still returns | |
1420 // 1/HZ. We check if clock_getres() works, but will ignore its reported | |
1421 // resolution for now. Hopefully as people move to new kernels, this | |
1422 // won't be a problem. | |
1423 struct timespec res; | |
1424 struct timespec tp; | |
1425 if (clock_getres_func (CLOCK_MONOTONIC, &res) == 0 && | |
1426 clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) { | |
1427 // yes, monotonic clock is supported | |
1428 _clock_gettime = clock_gettime_func; | |
1429 } else { | |
1430 // close librt if there is no monotonic clock | |
1431 dlclose(handle); | |
1432 } | |
1433 } | |
1434 } | |
1435 } | |
1436 | |
1437 #ifndef SYS_clock_getres | |
1438 | |
1439 #if defined(IA32) || defined(AMD64) | |
1440 #define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229) | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1441 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y) |
0 | 1442 #else |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1443 #warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time" |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1444 #define sys_clock_getres(x,y) -1 |
0 | 1445 #endif |
1446 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1447 #else |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1448 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y) |
0 | 1449 #endif |
1450 | |
1451 void os::Linux::fast_thread_clock_init() { | |
1452 if (!UseLinuxPosixThreadCPUClocks) { | |
1453 return; | |
1454 } | |
1455 clockid_t clockid; | |
1456 struct timespec tp; | |
1457 int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) = | |
1458 (int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid"); | |
1459 | |
1460 // Switch to using fast clocks for thread cpu time if | |
1461 // the sys_clock_getres() returns 0 error code. | |
1462 // Note, that some kernels may support the current thread | |
1463 // clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks | |
1464 // returned by the pthread_getcpuclockid(). | |
1465 // If the fast Posix clocks are supported then the sys_clock_getres() | |
1466 // must return at least tp.tv_sec == 0 which means a resolution | |
1467 // better than 1 sec. This is extra check for reliability. | |
1468 | |
1469 if(pthread_getcpuclockid_func && | |
1470 pthread_getcpuclockid_func(_main_thread, &clockid) == 0 && | |
1471 sys_clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) { | |
1472 | |
1473 _supports_fast_thread_cpu_time = true; | |
1474 _pthread_getcpuclockid = pthread_getcpuclockid_func; | |
1475 } | |
1476 } | |
1477 | |
1478 jlong os::javaTimeNanos() { | |
1479 if (Linux::supports_monotonic_clock()) { | |
1480 struct timespec tp; | |
1481 int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp); | |
1482 assert(status == 0, "gettime error"); | |
1483 jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec); | |
1484 return result; | |
1485 } else { | |
1486 timeval time; | |
1487 int status = gettimeofday(&time, NULL); | |
1488 assert(status != -1, "linux error"); | |
1489 jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec); | |
1490 return 1000 * usecs; | |
1491 } | |
1492 } | |
1493 | |
1494 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { | |
1495 if (Linux::supports_monotonic_clock()) { | |
1496 info_ptr->max_value = ALL_64_BITS; | |
1497 | |
1498 // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past | |
1499 info_ptr->may_skip_backward = false; // not subject to resetting or drifting | |
1500 info_ptr->may_skip_forward = false; // not subject to resetting or drifting | |
1501 } else { | |
1502 // gettimeofday - based on time in seconds since the Epoch thus does not wrap | |
1503 info_ptr->max_value = ALL_64_BITS; | |
1504 | |
1505 // gettimeofday is a real time clock so it skips | |
1506 info_ptr->may_skip_backward = true; | |
1507 info_ptr->may_skip_forward = true; | |
1508 } | |
1509 | |
1510 info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time | |
1511 } | |
1512 | |
1513 // Return the real, user, and system times in seconds from an | |
1514 // arbitrary fixed point in the past. | |
1515 bool os::getTimesSecs(double* process_real_time, | |
1516 double* process_user_time, | |
1517 double* process_system_time) { | |
1518 struct tms ticks; | |
1519 clock_t real_ticks = times(&ticks); | |
1520 | |
1521 if (real_ticks == (clock_t) (-1)) { | |
1522 return false; | |
1523 } else { | |
1524 double ticks_per_second = (double) clock_tics_per_sec; | |
1525 *process_user_time = ((double) ticks.tms_utime) / ticks_per_second; | |
1526 *process_system_time = ((double) ticks.tms_stime) / ticks_per_second; | |
1527 *process_real_time = ((double) real_ticks) / ticks_per_second; | |
1528 | |
1529 return true; | |
1530 } | |
1531 } | |
1532 | |
1533 | |
1534 char * os::local_time_string(char *buf, size_t buflen) { | |
1535 struct tm t; | |
1536 time_t long_time; | |
1537 time(&long_time); | |
1538 localtime_r(&long_time, &t); | |
1539 jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d", | |
1540 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, | |
1541 t.tm_hour, t.tm_min, t.tm_sec); | |
1542 return buf; | |
1543 } | |
1544 | |
548
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
516
diff
changeset
|
1545 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) { |
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
516
diff
changeset
|
1546 return localtime_r(clock, res); |
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
516
diff
changeset
|
1547 } |
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
516
diff
changeset
|
1548 |
0 | 1549 //////////////////////////////////////////////////////////////////////////////// |
1550 // runtime exit support | |
1551 | |
1552 // Note: os::shutdown() might be called very early during initialization, or | |
1553 // called from signal handler. Before adding something to os::shutdown(), make | |
1554 // sure it is async-safe and can handle partially initialized VM. | |
1555 void os::shutdown() { | |
1556 | |
1557 // allow PerfMemory to attempt cleanup of any persistent resources | |
1558 perfMemory_exit(); | |
1559 | |
1560 // needs to remove object in file system | |
1561 AttachListener::abort(); | |
1562 | |
1563 // flush buffered output, finish log files | |
1564 ostream_abort(); | |
1565 | |
1566 // Check for abort hook | |
1567 abort_hook_t abort_hook = Arguments::abort_hook(); | |
1568 if (abort_hook != NULL) { | |
1569 abort_hook(); | |
1570 } | |
1571 | |
1572 } | |
1573 | |
1574 // Note: os::abort() might be called very early during initialization, or | |
1575 // called from signal handler. Before adding something to os::abort(), make | |
1576 // sure it is async-safe and can handle partially initialized VM. | |
1577 void os::abort(bool dump_core) { | |
1578 os::shutdown(); | |
1579 if (dump_core) { | |
1580 #ifndef PRODUCT | |
1581 fdStream out(defaultStream::output_fd()); | |
1582 out.print_raw("Current thread is "); | |
1583 char buf[16]; | |
1584 jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id()); | |
1585 out.print_raw_cr(buf); | |
1586 out.print_raw_cr("Dumping core ..."); | |
1587 #endif | |
1588 ::abort(); // dump core | |
1589 } | |
1590 | |
1591 ::exit(1); | |
1592 } | |
1593 | |
1594 // Die immediately, no exit hook, no abort hook, no cleanup. | |
1595 void os::die() { | |
1596 // _exit() on LinuxThreads only kills current thread | |
1597 ::abort(); | |
1598 } | |
1599 | |
1600 // unused on linux for now. | |
1601 void os::set_error_file(const char *logfile) {} | |
1602 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1603 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1604 // 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
|
1605 // from src/solaris/hpi/src/system_md.c |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1606 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1607 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
|
1608 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1609 if (errno == 0) return 0; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1610 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1611 const char *s = ::strerror(errno); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1612 size_t n = ::strlen(s); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1613 if (n >= len) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1614 n = len - 1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1615 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1616 ::strncpy(buf, s, n); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1617 buf[n] = '\0'; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1618 return n; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1619 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1620 |
0 | 1621 intx os::current_thread_id() { return (intx)pthread_self(); } |
1622 int os::current_process_id() { | |
1623 | |
1624 // Under the old linux thread library, linux gives each thread | |
1625 // its own process id. Because of this each thread will return | |
1626 // a different pid if this method were to return the result | |
1627 // of getpid(2). Linux provides no api that returns the pid | |
1628 // of the launcher thread for the vm. This implementation | |
1629 // returns a unique pid, the pid of the launcher thread | |
1630 // that starts the vm 'process'. | |
1631 | |
1632 // Under the NPTL, getpid() returns the same pid as the | |
1633 // launcher thread rather than a unique pid per thread. | |
1634 // Use gettid() if you want the old pre NPTL behaviour. | |
1635 | |
1636 // if you are looking for the result of a call to getpid() that | |
1637 // returns a unique pid for the calling thread, then look at the | |
1638 // OSThread::thread_id() method in osThread_linux.hpp file | |
1639 | |
1640 return (int)(_initial_pid ? _initial_pid : getpid()); | |
1641 } | |
1642 | |
1643 // DLL functions | |
1644 | |
1645 const char* os::dll_file_extension() { return ".so"; } | |
1646 | |
2130
34d64ad817f4
7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents:
2033
diff
changeset
|
1647 // 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:
2033
diff
changeset
|
1648 // 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:
2033
diff
changeset
|
1649 const char* os::get_temp_directory() { return "/tmp"; } |
0 | 1650 |
691 | 1651 static bool file_exists(const char* filename) { |
1652 struct stat statbuf; | |
1653 if (filename == NULL || strlen(filename) == 0) { | |
1654 return false; | |
1655 } | |
1656 return os::stat(filename, &statbuf) == 0; | |
1657 } | |
1658 | |
1659 void os::dll_build_name(char* buffer, size_t buflen, | |
1660 const char* pname, const char* fname) { | |
1661 // Copied from libhpi | |
242 | 1662 const size_t pnamelen = pname ? strlen(pname) : 0; |
1663 | |
691 | 1664 // Quietly truncate on buffer overflow. Should be an error. |
242 | 1665 if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { |
1666 *buffer = '\0'; | |
1667 return; | |
1668 } | |
1669 | |
1670 if (pnamelen == 0) { | |
691 | 1671 snprintf(buffer, buflen, "lib%s.so", fname); |
1672 } else if (strchr(pname, *os::path_separator()) != NULL) { | |
1673 int n; | |
1674 char** pelements = split_path(pname, &n); | |
1675 for (int i = 0 ; i < n ; i++) { | |
1676 // Really shouldn't be NULL, but check can't hurt | |
1677 if (pelements[i] == NULL || strlen(pelements[i]) == 0) { | |
1678 continue; // skip the empty path values | |
1679 } | |
1680 snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname); | |
1681 if (file_exists(buffer)) { | |
1682 break; | |
1683 } | |
1684 } | |
1685 // release the storage | |
1686 for (int i = 0 ; i < n ; i++) { | |
1687 if (pelements[i] != NULL) { | |
1688 FREE_C_HEAP_ARRAY(char, pelements[i]); | |
1689 } | |
1690 } | |
1691 if (pelements != NULL) { | |
1692 FREE_C_HEAP_ARRAY(char*, pelements); | |
1693 } | |
242 | 1694 } else { |
691 | 1695 snprintf(buffer, buflen, "%s/lib%s.so", pname, fname); |
242 | 1696 } |
1697 } | |
1698 | |
0 | 1699 const char* os::get_current_directory(char *buf, int buflen) { |
1700 return getcwd(buf, buflen); | |
1701 } | |
1702 | |
1703 // check if addr is inside libjvm[_g].so | |
1704 bool os::address_is_in_vm(address addr) { | |
1705 static address libjvm_base_addr; | |
1706 Dl_info dlinfo; | |
1707 | |
1708 if (libjvm_base_addr == NULL) { | |
1709 dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo); | |
1710 libjvm_base_addr = (address)dlinfo.dli_fbase; | |
1711 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); | |
1712 } | |
1713 | |
1714 if (dladdr((void *)addr, &dlinfo)) { | |
1715 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; | |
1716 } | |
1717 | |
1718 return false; | |
1719 } | |
1720 | |
1721 bool os::dll_address_to_function_name(address addr, char *buf, | |
1722 int buflen, int *offset) { | |
1723 Dl_info dlinfo; | |
1724 | |
1725 if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) { | |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1726 if (buf != NULL) { |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1727 if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1728 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1729 } |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1730 } |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1731 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; |
0 | 1732 return true; |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1733 } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1734 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), |
4803 | 1735 buf, buflen, offset, dlinfo.dli_fname)) { |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1736 return true; |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1737 } |
0 | 1738 } |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1739 |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1740 if (buf != NULL) buf[0] = '\0'; |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1741 if (offset != NULL) *offset = -1; |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1742 return false; |
0 | 1743 } |
1744 | |
1745 struct _address_to_library_name { | |
1746 address addr; // input : memory address | |
1747 size_t buflen; // size of fname | |
1748 char* fname; // output: library name | |
1749 address base; // library base addr | |
1750 }; | |
1751 | |
1752 static int address_to_library_name_callback(struct dl_phdr_info *info, | |
1753 size_t size, void *data) { | |
1754 int i; | |
1755 bool found = false; | |
1756 address libbase = NULL; | |
1757 struct _address_to_library_name * d = (struct _address_to_library_name *)data; | |
1758 | |
1759 // iterate through all loadable segments | |
1760 for (i = 0; i < info->dlpi_phnum; i++) { | |
1761 address segbase = (address)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr); | |
1762 if (info->dlpi_phdr[i].p_type == PT_LOAD) { | |
1763 // base address of a library is the lowest address of its loaded | |
1764 // segments. | |
1765 if (libbase == NULL || libbase > segbase) { | |
1766 libbase = segbase; | |
1767 } | |
1768 // see if 'addr' is within current segment | |
1769 if (segbase <= d->addr && | |
1770 d->addr < segbase + info->dlpi_phdr[i].p_memsz) { | |
1771 found = true; | |
1772 } | |
1773 } | |
1774 } | |
1775 | |
1776 // dlpi_name is NULL or empty if the ELF file is executable, return 0 | |
1777 // so dll_address_to_library_name() can fall through to use dladdr() which | |
1778 // can figure out executable name from argv[0]. | |
1779 if (found && info->dlpi_name && info->dlpi_name[0]) { | |
1780 d->base = libbase; | |
1781 if (d->fname) { | |
1782 jio_snprintf(d->fname, d->buflen, "%s", info->dlpi_name); | |
1783 } | |
1784 return 1; | |
1785 } | |
1786 return 0; | |
1787 } | |
1788 | |
1789 bool os::dll_address_to_library_name(address addr, char* buf, | |
1790 int buflen, int* offset) { | |
1791 Dl_info dlinfo; | |
1792 struct _address_to_library_name data; | |
1793 | |
1794 // There is a bug in old glibc dladdr() implementation that it could resolve | |
1795 // to wrong library name if the .so file has a base address != NULL. Here | |
1796 // we iterate through the program headers of all loaded libraries to find | |
1797 // out which library 'addr' really belongs to. This workaround can be | |
1798 // removed once the minimum requirement for glibc is moved to 2.3.x. | |
1799 data.addr = addr; | |
1800 data.fname = buf; | |
1801 data.buflen = buflen; | |
1802 data.base = NULL; | |
1803 int rslt = dl_iterate_phdr(address_to_library_name_callback, (void *)&data); | |
1804 | |
1805 if (rslt) { | |
1806 // buf already contains library name | |
1807 if (offset) *offset = addr - data.base; | |
1808 return true; | |
1809 } else if (dladdr((void*)addr, &dlinfo)){ | |
1810 if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); | |
1811 if (offset) *offset = addr - (address)dlinfo.dli_fbase; | |
1812 return true; | |
1813 } else { | |
1814 if (buf) buf[0] = '\0'; | |
1815 if (offset) *offset = -1; | |
1816 return false; | |
1817 } | |
1818 } | |
1819 | |
1820 // Loads .dll/.so and | |
1821 // in case of error it checks if .dll/.so was built for the | |
1822 // same architecture as Hotspot is running on | |
1823 | |
1824 void * os::dll_load(const char *filename, char *ebuf, int ebuflen) | |
1825 { | |
1826 void * result= ::dlopen(filename, RTLD_LAZY); | |
1827 if (result != NULL) { | |
1828 // Successful loading | |
1829 return result; | |
1830 } | |
1831 | |
1832 Elf32_Ehdr elf_head; | |
1833 | |
1834 // Read system error message into ebuf | |
1835 // It may or may not be overwritten below | |
1836 ::strncpy(ebuf, ::dlerror(), ebuflen-1); | |
1837 ebuf[ebuflen-1]='\0'; | |
1838 int diag_msg_max_length=ebuflen-strlen(ebuf); | |
1839 char* diag_msg_buf=ebuf+strlen(ebuf); | |
1840 | |
1841 if (diag_msg_max_length==0) { | |
1842 // No more space in ebuf for additional diagnostics message | |
1843 return NULL; | |
1844 } | |
1845 | |
1846 | |
1847 int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK); | |
1848 | |
1849 if (file_descriptor < 0) { | |
1850 // Can't open library, report dlerror() message | |
1851 return NULL; | |
1852 } | |
1853 | |
1854 bool failed_to_read_elf_head= | |
1855 (sizeof(elf_head)!= | |
1856 (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ; | |
1857 | |
1858 ::close(file_descriptor); | |
1859 if (failed_to_read_elf_head) { | |
1860 // file i/o error - report dlerror() msg | |
1861 return NULL; | |
1862 } | |
1863 | |
1864 typedef struct { | |
1865 Elf32_Half code; // Actual value as defined in elf.h | |
1866 Elf32_Half compat_class; // Compatibility of archs at VM's sense | |
1867 char elf_class; // 32 or 64 bit | |
1868 char endianess; // MSB or LSB | |
1869 char* name; // String representation | |
1870 } arch_t; | |
1871 | |
1872 #ifndef EM_486 | |
1873 #define EM_486 6 /* Intel 80486 */ | |
1874 #endif | |
1875 | |
1876 static const arch_t arch_array[]={ | |
1877 {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, | |
1878 {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, | |
1879 {EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"}, | |
1880 {EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"}, | |
1881 {EM_SPARC, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, | |
1882 {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, | |
1883 {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"}, | |
1884 {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"}, | |
1010 | 1885 {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}, |
1886 {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"}, | |
1887 {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"}, | |
1888 {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"}, | |
1889 {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"}, | |
1890 {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"}, | |
1891 {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"}, | |
1892 {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"} | |
0 | 1893 }; |
1894 | |
1895 #if (defined IA32) | |
1896 static Elf32_Half running_arch_code=EM_386; | |
1897 #elif (defined AMD64) | |
1898 static Elf32_Half running_arch_code=EM_X86_64; | |
1899 #elif (defined IA64) | |
1900 static Elf32_Half running_arch_code=EM_IA_64; | |
1901 #elif (defined __sparc) && (defined _LP64) | |
1902 static Elf32_Half running_arch_code=EM_SPARCV9; | |
1903 #elif (defined __sparc) && (!defined _LP64) | |
1904 static Elf32_Half running_arch_code=EM_SPARC; | |
1905 #elif (defined __powerpc64__) | |
1906 static Elf32_Half running_arch_code=EM_PPC64; | |
1907 #elif (defined __powerpc__) | |
1908 static Elf32_Half running_arch_code=EM_PPC; | |
1010 | 1909 #elif (defined ARM) |
1910 static Elf32_Half running_arch_code=EM_ARM; | |
1911 #elif (defined S390) | |
1912 static Elf32_Half running_arch_code=EM_S390; | |
1913 #elif (defined ALPHA) | |
1914 static Elf32_Half running_arch_code=EM_ALPHA; | |
1915 #elif (defined MIPSEL) | |
1916 static Elf32_Half running_arch_code=EM_MIPS_RS3_LE; | |
1917 #elif (defined PARISC) | |
1918 static Elf32_Half running_arch_code=EM_PARISC; | |
1919 #elif (defined MIPS) | |
1920 static Elf32_Half running_arch_code=EM_MIPS; | |
1921 #elif (defined M68K) | |
1922 static Elf32_Half running_arch_code=EM_68K; | |
0 | 1923 #else |
1924 #error Method os::dll_load requires that one of following is defined:\ | |
1010 | 1925 IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K |
0 | 1926 #endif |
1927 | |
1928 // Identify compatability class for VM's architecture and library's architecture | |
1929 // Obtain string descriptions for architectures | |
1930 | |
1931 arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL}; | |
1932 int running_arch_index=-1; | |
1933 | |
1934 for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) { | |
1935 if (running_arch_code == arch_array[i].code) { | |
1936 running_arch_index = i; | |
1937 } | |
1938 if (lib_arch.code == arch_array[i].code) { | |
1939 lib_arch.compat_class = arch_array[i].compat_class; | |
1940 lib_arch.name = arch_array[i].name; | |
1941 } | |
1942 } | |
1943 | |
1944 assert(running_arch_index != -1, | |
1945 "Didn't find running architecture code (running_arch_code) in arch_array"); | |
1946 if (running_arch_index == -1) { | |
1947 // Even though running architecture detection failed | |
1948 // we may still continue with reporting dlerror() message | |
1949 return NULL; | |
1950 } | |
1951 | |
1952 if (lib_arch.endianess != arch_array[running_arch_index].endianess) { | |
1953 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)"); | |
1954 return NULL; | |
1955 } | |
1956 | |
1010 | 1957 #ifndef S390 |
0 | 1958 if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) { |
1959 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)"); | |
1960 return NULL; | |
1961 } | |
1010 | 1962 #endif // !S390 |
0 | 1963 |
1964 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) { | |
1965 if ( lib_arch.name!=NULL ) { | |
1966 ::snprintf(diag_msg_buf, diag_msg_max_length-1, | |
1967 " (Possible cause: can't load %s-bit .so on a %s-bit platform)", | |
1968 lib_arch.name, arch_array[running_arch_index].name); | |
1969 } else { | |
1970 ::snprintf(diag_msg_buf, diag_msg_max_length-1, | |
1971 " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)", | |
1972 lib_arch.code, | |
1973 arch_array[running_arch_index].name); | |
1974 } | |
1975 } | |
1976 | |
1977 return NULL; | |
1978 } | |
1979 | |
242 | 1980 /* |
1981 * glibc-2.0 libdl is not MT safe. If you are building with any glibc, | |
1982 * chances are you might want to run the generated bits against glibc-2.0 | |
1983 * libdl.so, so always use locking for any version of glibc. | |
1984 */ | |
1985 void* os::dll_lookup(void* handle, const char* name) { | |
1986 pthread_mutex_lock(&dl_mutex); | |
1987 void* res = dlsym(handle, name); | |
1988 pthread_mutex_unlock(&dl_mutex); | |
1989 return res; | |
1990 } | |
0 | 1991 |
1992 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1993 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
|
1994 int fd = ::open(filename, O_RDONLY); |
0 | 1995 if (fd == -1) { |
1996 return false; | |
1997 } | |
1998 | |
1999 char buf[32]; | |
2000 int bytes; | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2001 while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) { |
0 | 2002 st->print_raw(buf, bytes); |
2003 } | |
2004 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2005 ::close(fd); |
0 | 2006 |
2007 return true; | |
2008 } | |
2009 | |
2010 void os::print_dll_info(outputStream *st) { | |
2011 st->print_cr("Dynamic libraries:"); | |
2012 | |
2013 char fname[32]; | |
2014 pid_t pid = os::Linux::gettid(); | |
2015 | |
2016 jio_snprintf(fname, sizeof(fname), "/proc/%d/maps", pid); | |
2017 | |
2018 if (!_print_ascii_file(fname, st)) { | |
2019 st->print("Can not get library information for pid = %d\n", pid); | |
2020 } | |
2021 } | |
2022 | |
2023 | |
2024 void os::print_os_info(outputStream* st) { | |
2025 st->print("OS:"); | |
2026 | |
2027 // Try to identify popular distros. | |
2028 // Most Linux distributions have /etc/XXX-release file, which contains | |
2029 // the OS version string. Some have more than one /etc/XXX-release file | |
2030 // (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.), | |
2031 // so the order is important. | |
2032 if (!_print_ascii_file("/etc/mandrake-release", st) && | |
2033 !_print_ascii_file("/etc/sun-release", st) && | |
2034 !_print_ascii_file("/etc/redhat-release", st) && | |
2035 !_print_ascii_file("/etc/SuSE-release", st) && | |
2036 !_print_ascii_file("/etc/turbolinux-release", st) && | |
2037 !_print_ascii_file("/etc/gentoo-release", st) && | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2038 !_print_ascii_file("/etc/debian_version", st) && |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2039 !_print_ascii_file("/etc/ltib-release", st) && |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2040 !_print_ascii_file("/etc/angstrom-version", st)) { |
0 | 2041 st->print("Linux"); |
2042 } | |
2043 st->cr(); | |
2044 | |
2045 // kernel | |
2046 st->print("uname:"); | |
2047 struct utsname name; | |
2048 uname(&name); | |
2049 st->print(name.sysname); st->print(" "); | |
2050 st->print(name.release); st->print(" "); | |
2051 st->print(name.version); st->print(" "); | |
2052 st->print(name.machine); | |
2053 st->cr(); | |
2054 | |
2055 // Print warning if unsafe chroot environment detected | |
2056 if (unsafe_chroot_detected) { | |
2057 st->print("WARNING!! "); | |
2058 st->print_cr(unstable_chroot_error); | |
2059 } | |
2060 | |
2061 // libc, pthread | |
2062 st->print("libc:"); | |
2063 st->print(os::Linux::glibc_version()); st->print(" "); | |
2064 st->print(os::Linux::libpthread_version()); st->print(" "); | |
2065 if (os::Linux::is_LinuxThreads()) { | |
2066 st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed"); | |
2067 } | |
2068 st->cr(); | |
2069 | |
2070 // rlimit | |
2071 st->print("rlimit:"); | |
2072 struct rlimit rlim; | |
2073 | |
2074 st->print(" STACK "); | |
2075 getrlimit(RLIMIT_STACK, &rlim); | |
2076 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); | |
2077 else st->print("%uk", rlim.rlim_cur >> 10); | |
2078 | |
2079 st->print(", CORE "); | |
2080 getrlimit(RLIMIT_CORE, &rlim); | |
2081 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); | |
2082 else st->print("%uk", rlim.rlim_cur >> 10); | |
2083 | |
2084 st->print(", NPROC "); | |
2085 getrlimit(RLIMIT_NPROC, &rlim); | |
2086 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); | |
2087 else st->print("%d", rlim.rlim_cur); | |
2088 | |
2089 st->print(", NOFILE "); | |
2090 getrlimit(RLIMIT_NOFILE, &rlim); | |
2091 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); | |
2092 else st->print("%d", rlim.rlim_cur); | |
2093 | |
2094 st->print(", AS "); | |
2095 getrlimit(RLIMIT_AS, &rlim); | |
2096 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity"); | |
2097 else st->print("%uk", rlim.rlim_cur >> 10); | |
2098 st->cr(); | |
2099 | |
2100 // load average | |
2101 st->print("load average:"); | |
2102 double loadavg[3]; | |
2103 os::loadavg(loadavg, 3); | |
2104 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); | |
2105 st->cr(); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2106 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2107 // meminfo |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2108 st->print("\n/proc/meminfo:\n"); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2109 _print_ascii_file("/proc/meminfo", st); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2110 st->cr(); |
0 | 2111 } |
2112 | |
3800
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
3358
diff
changeset
|
2113 void os::pd_print_cpu_info(outputStream* st) { |
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
3358
diff
changeset
|
2114 st->print("\n/proc/cpuinfo:\n"); |
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
3358
diff
changeset
|
2115 if (!_print_ascii_file("/proc/cpuinfo", st)) { |
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
3358
diff
changeset
|
2116 st->print(" <Not Available>"); |
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
3358
diff
changeset
|
2117 } |
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
3358
diff
changeset
|
2118 st->cr(); |
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
3358
diff
changeset
|
2119 } |
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
3358
diff
changeset
|
2120 |
0 | 2121 void os::print_memory_info(outputStream* st) { |
2122 | |
2123 st->print("Memory:"); | |
2124 st->print(" %dk page", os::vm_page_size()>>10); | |
2125 | |
2126 // values in struct sysinfo are "unsigned long" | |
2127 struct sysinfo si; | |
2128 sysinfo(&si); | |
2129 | |
2130 st->print(", physical " UINT64_FORMAT "k", | |
2131 os::physical_memory() >> 10); | |
2132 st->print("(" UINT64_FORMAT "k free)", | |
2133 os::available_memory() >> 10); | |
2134 st->print(", swap " UINT64_FORMAT "k", | |
2135 ((jlong)si.totalswap * si.mem_unit) >> 10); | |
2136 st->print("(" UINT64_FORMAT "k free)", | |
2137 ((jlong)si.freeswap * si.mem_unit) >> 10); | |
2138 st->cr(); | |
2139 } | |
2140 | |
2141 // Taken from /usr/include/bits/siginfo.h Supposed to be architecture specific | |
2142 // but they're the same for all the linux arch that we support | |
2143 // and they're the same for solaris but there's no common place to put this. | |
2144 const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR", | |
2145 "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG", | |
2146 "ILL_COPROC", "ILL_BADSTK" }; | |
2147 | |
2148 const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV", | |
2149 "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES", | |
2150 "FPE_FLTINV", "FPE_FLTSUB", "FPE_FLTDEN" }; | |
2151 | |
2152 const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" }; | |
2153 | |
2154 const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" }; | |
2155 | |
2156 void os::print_siginfo(outputStream* st, void* siginfo) { | |
2157 st->print("siginfo:"); | |
2158 | |
2159 const int buflen = 100; | |
2160 char buf[buflen]; | |
2161 siginfo_t *si = (siginfo_t*)siginfo; | |
2162 st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen)); | |
2163 if (si->si_errno != 0 && strerror_r(si->si_errno, buf, buflen) == 0) { | |
2164 st->print("si_errno=%s", buf); | |
2165 } else { | |
2166 st->print("si_errno=%d", si->si_errno); | |
2167 } | |
2168 const int c = si->si_code; | |
2169 assert(c > 0, "unexpected si_code"); | |
2170 switch (si->si_signo) { | |
2171 case SIGILL: | |
2172 st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]); | |
2173 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2174 break; | |
2175 case SIGFPE: | |
2176 st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]); | |
2177 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2178 break; | |
2179 case SIGSEGV: | |
2180 st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]); | |
2181 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2182 break; | |
2183 case SIGBUS: | |
2184 st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]); | |
2185 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2186 break; | |
2187 default: | |
2188 st->print(", si_code=%d", si->si_code); | |
2189 // no si_addr | |
2190 } | |
2191 | |
2192 if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) && | |
2193 UseSharedSpaces) { | |
2194 FileMapInfo* mapinfo = FileMapInfo::current_info(); | |
2195 if (mapinfo->is_in_shared_space(si->si_addr)) { | |
2196 st->print("\n\nError accessing class data sharing archive." \ | |
2197 " Mapped file inaccessible during execution, " \ | |
2198 " possible disk/network problem."); | |
2199 } | |
2200 } | |
2201 st->cr(); | |
2202 } | |
2203 | |
2204 | |
2205 static void print_signal_handler(outputStream* st, int sig, | |
2206 char* buf, size_t buflen); | |
2207 | |
2208 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { | |
2209 st->print_cr("Signal Handlers:"); | |
2210 print_signal_handler(st, SIGSEGV, buf, buflen); | |
2211 print_signal_handler(st, SIGBUS , buf, buflen); | |
2212 print_signal_handler(st, SIGFPE , buf, buflen); | |
2213 print_signal_handler(st, SIGPIPE, buf, buflen); | |
2214 print_signal_handler(st, SIGXFSZ, buf, buflen); | |
2215 print_signal_handler(st, SIGILL , buf, buflen); | |
2216 print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen); | |
2217 print_signal_handler(st, SR_signum, buf, buflen); | |
2218 print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen); | |
2219 print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen); | |
2220 print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen); | |
2221 print_signal_handler(st, BREAK_SIGNAL, buf, buflen); | |
2222 } | |
2223 | |
2224 static char saved_jvm_path[MAXPATHLEN] = {0}; | |
2225 | |
2226 // Find the full path to the current module, libjvm.so or libjvm_g.so | |
1642 | 2227 void os::jvm_path(char *buf, jint buflen) { |
0 | 2228 // Error checking. |
1642 | 2229 if (buflen < MAXPATHLEN) { |
0 | 2230 assert(false, "must use a large-enough buffer"); |
2231 buf[0] = '\0'; | |
2232 return; | |
2233 } | |
2234 // Lazy resolve the path to current module. | |
2235 if (saved_jvm_path[0] != 0) { | |
2236 strcpy(buf, saved_jvm_path); | |
2237 return; | |
2238 } | |
2239 | |
2240 char dli_fname[MAXPATHLEN]; | |
2241 bool ret = dll_address_to_library_name( | |
2242 CAST_FROM_FN_PTR(address, os::jvm_path), | |
2243 dli_fname, sizeof(dli_fname), NULL); | |
2244 assert(ret != 0, "cannot locate libjvm"); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2245 char *rp = realpath(dli_fname, buf); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2246 if (rp == NULL) |
513
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
477
diff
changeset
|
2247 return; |
0 | 2248 |
2302
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
2249 if (Arguments::created_by_gamma_launcher()) { |
0 | 2250 // Support for the gamma launcher. Typical value for buf is |
2251 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at | |
2252 // the right place in the string, then assume we are installed in a JDK and | |
2253 // we're done. Otherwise, check for a JAVA_HOME environment variable and fix | |
2254 // up the path so it looks like libjvm.so is installed there (append a | |
2255 // fake suffix hotspot/libjvm.so). | |
2256 const char *p = buf + strlen(buf) - 1; | |
2257 for (int count = 0; p > buf && count < 5; ++count) { | |
2258 for (--p; p > buf && *p != '/'; --p) | |
2259 /* empty */ ; | |
2260 } | |
2261 | |
2262 if (strncmp(p, "/jre/lib/", 9) != 0) { | |
2263 // Look for JAVA_HOME in the environment. | |
2264 char* java_home_var = ::getenv("JAVA_HOME"); | |
2265 if (java_home_var != NULL && java_home_var[0] != 0) { | |
1642 | 2266 char* jrelib_p; |
2267 int len; | |
2268 | |
0 | 2269 // Check the current module name "libjvm.so" or "libjvm_g.so". |
2270 p = strrchr(buf, '/'); | |
2271 assert(strstr(p, "/libjvm") == p, "invalid library name"); | |
2272 p = strstr(p, "_g") ? "_g" : ""; | |
2273 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2274 rp = realpath(java_home_var, buf); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2275 if (rp == NULL) |
513
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
477
diff
changeset
|
2276 return; |
1642 | 2277 |
2278 // determine if this is a legacy image or modules image | |
2279 // modules image doesn't have "jre" subdirectory | |
2280 len = strlen(buf); | |
2281 jrelib_p = buf + len; | |
2282 snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch); | |
2283 if (0 != access(buf, F_OK)) { | |
2284 snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch); | |
2285 } | |
2286 | |
0 | 2287 if (0 == access(buf, F_OK)) { |
2288 // Use current module name "libjvm[_g].so" instead of | |
2289 // "libjvm"debug_only("_g")".so" since for fastdebug version | |
2290 // we should have "libjvm.so" but debug_only("_g") adds "_g"! | |
1642 | 2291 len = strlen(buf); |
2292 snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p); | |
0 | 2293 } else { |
2294 // Go back to path of .so | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2295 rp = realpath(dli_fname, buf); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2296 if (rp == NULL) |
513
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
477
diff
changeset
|
2297 return; |
0 | 2298 } |
2299 } | |
2300 } | |
2301 } | |
2302 | |
2303 strcpy(saved_jvm_path, buf); | |
2304 } | |
2305 | |
2306 void os::print_jni_name_prefix_on(outputStream* st, int args_size) { | |
2307 // no prefix required, not even "_" | |
2308 } | |
2309 | |
2310 void os::print_jni_name_suffix_on(outputStream* st, int args_size) { | |
2311 // no suffix required | |
2312 } | |
2313 | |
2314 //////////////////////////////////////////////////////////////////////////////// | |
2315 // sun.misc.Signal support | |
2316 | |
2317 static volatile jint sigint_count = 0; | |
2318 | |
2319 static void | |
2320 UserHandler(int sig, void *siginfo, void *context) { | |
2321 // 4511530 - sem_post is serialized and handled by the manager thread. When | |
2322 // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We | |
2323 // don't want to flood the manager thread with sem_post requests. | |
2324 if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1) | |
2325 return; | |
2326 | |
2327 // Ctrl-C is pressed during error reporting, likely because the error | |
2328 // handler fails to abort. Let VM die immediately. | |
2329 if (sig == SIGINT && is_error_reported()) { | |
2330 os::die(); | |
2331 } | |
2332 | |
2333 os::signal_notify(sig); | |
2334 } | |
2335 | |
2336 void* os::user_handler() { | |
2337 return CAST_FROM_FN_PTR(void*, UserHandler); | |
2338 } | |
2339 | |
2340 extern "C" { | |
2341 typedef void (*sa_handler_t)(int); | |
2342 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); | |
2343 } | |
2344 | |
2345 void* os::signal(int signal_number, void* handler) { | |
2346 struct sigaction sigAct, oldSigAct; | |
2347 | |
2348 sigfillset(&(sigAct.sa_mask)); | |
2349 sigAct.sa_flags = SA_RESTART|SA_SIGINFO; | |
2350 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler); | |
2351 | |
2352 if (sigaction(signal_number, &sigAct, &oldSigAct)) { | |
2353 // -1 means registration failed | |
2354 return (void *)-1; | |
2355 } | |
2356 | |
2357 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler); | |
2358 } | |
2359 | |
2360 void os::signal_raise(int signal_number) { | |
2361 ::raise(signal_number); | |
2362 } | |
2363 | |
2364 /* | |
2365 * The following code is moved from os.cpp for making this | |
2366 * code platform specific, which it is by its very nature. | |
2367 */ | |
2368 | |
2369 // Will be modified when max signal is changed to be dynamic | |
2370 int os::sigexitnum_pd() { | |
2371 return NSIG; | |
2372 } | |
2373 | |
2374 // a counter for each possible signal value | |
2375 static volatile jint pending_signals[NSIG+1] = { 0 }; | |
2376 | |
2377 // Linux(POSIX) specific hand shaking semaphore. | |
2378 static sem_t sig_sem; | |
2379 | |
2380 void os::signal_init_pd() { | |
2381 // Initialize signal structures | |
2382 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); | |
2383 | |
2384 // Initialize signal semaphore | |
2385 ::sem_init(&sig_sem, 0, 0); | |
2386 } | |
2387 | |
2388 void os::signal_notify(int sig) { | |
2389 Atomic::inc(&pending_signals[sig]); | |
2390 ::sem_post(&sig_sem); | |
2391 } | |
2392 | |
2393 static int check_pending_signals(bool wait) { | |
2394 Atomic::store(0, &sigint_count); | |
2395 for (;;) { | |
2396 for (int i = 0; i < NSIG + 1; i++) { | |
2397 jint n = pending_signals[i]; | |
2398 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { | |
2399 return i; | |
2400 } | |
2401 } | |
2402 if (!wait) { | |
2403 return -1; | |
2404 } | |
2405 JavaThread *thread = JavaThread::current(); | |
2406 ThreadBlockInVM tbivm(thread); | |
2407 | |
2408 bool threadIsSuspended; | |
2409 do { | |
2410 thread->set_suspend_equivalent(); | |
2411 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() | |
2412 ::sem_wait(&sig_sem); | |
2413 | |
2414 // were we externally suspended while we were waiting? | |
2415 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); | |
2416 if (threadIsSuspended) { | |
2417 // | |
2418 // The semaphore has been incremented, but while we were waiting | |
2419 // another thread suspended us. We don't want to continue running | |
2420 // while suspended because that would surprise the thread that | |
2421 // suspended us. | |
2422 // | |
2423 ::sem_post(&sig_sem); | |
2424 | |
2425 thread->java_suspend_self(); | |
2426 } | |
2427 } while (threadIsSuspended); | |
2428 } | |
2429 } | |
2430 | |
2431 int os::signal_lookup() { | |
2432 return check_pending_signals(false); | |
2433 } | |
2434 | |
2435 int os::signal_wait() { | |
2436 return check_pending_signals(true); | |
2437 } | |
2438 | |
2439 //////////////////////////////////////////////////////////////////////////////// | |
2440 // Virtual Memory | |
2441 | |
2442 int os::vm_page_size() { | |
2443 // Seems redundant as all get out | |
2444 assert(os::Linux::page_size() != -1, "must call os::init"); | |
2445 return os::Linux::page_size(); | |
2446 } | |
2447 | |
2448 // Solaris allocates memory by pages. | |
2449 int os::vm_allocation_granularity() { | |
2450 assert(os::Linux::page_size() != -1, "must call os::init"); | |
2451 return os::Linux::page_size(); | |
2452 } | |
2453 | |
2454 // Rationale behind this function: | |
2455 // current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable | |
2456 // mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get | |
2457 // samples for JITted code. Here we create private executable mapping over the code cache | |
2458 // and then we can use standard (well, almost, as mapping can change) way to provide | |
2459 // info for the reporting script by storing timestamp and location of symbol | |
2460 void linux_wrap_code(char* base, size_t size) { | |
2461 static volatile jint cnt = 0; | |
2462 | |
2463 if (!UseOprofile) { | |
2464 return; | |
2465 } | |
2466 | |
1497
96d554193f72
6944822: Fix for 6938627 exposes problem with hard-coded buffer sizes
coleenp
parents:
1353
diff
changeset
|
2467 char buf[PATH_MAX+1]; |
0 | 2468 int num = Atomic::add(1, &cnt); |
2469 | |
1353
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
1325
diff
changeset
|
2470 snprintf(buf, sizeof(buf), "%s/hs-vm-%d-%d", |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
1325
diff
changeset
|
2471 os::get_temp_directory(), os::current_process_id(), num); |
0 | 2472 unlink(buf); |
2473 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2474 int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU); |
0 | 2475 |
2476 if (fd != -1) { | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2477 off_t rv = ::lseek(fd, size-2, SEEK_SET); |
0 | 2478 if (rv != (off_t)-1) { |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2479 if (::write(fd, "", 1) == 1) { |
0 | 2480 mmap(base, size, |
2481 PROT_READ|PROT_WRITE|PROT_EXEC, | |
2482 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0); | |
2483 } | |
2484 } | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2485 ::close(fd); |
0 | 2486 unlink(buf); |
2487 } | |
2488 } | |
2489 | |
2490 // NOTE: Linux kernel does not really reserve the pages for us. | |
2491 // All it does is to check if there are enough free pages | |
2492 // left at the time of mmap(). This could be a potential | |
2493 // problem. | |
656 | 2494 bool os::commit_memory(char* addr, size_t size, bool exec) { |
2495 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; | |
2496 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, | |
0 | 2497 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); |
3885 | 2498 if (res != (uintptr_t) MAP_FAILED) { |
2499 if (UseNUMAInterleaving) { | |
2500 numa_make_global(addr, size); | |
2501 } | |
2502 return true; | |
2503 } | |
2504 return false; | |
0 | 2505 } |
2506 | |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2507 // Define MAP_HUGETLB here so we can build HotSpot on old systems. |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2508 #ifndef MAP_HUGETLB |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2509 #define MAP_HUGETLB 0x40000 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2510 #endif |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2511 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2512 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems. |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2513 #ifndef MADV_HUGEPAGE |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2514 #define MADV_HUGEPAGE 14 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2515 #endif |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2516 |
656 | 2517 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, |
2518 bool exec) { | |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2519 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2520 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2521 uintptr_t res = |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2522 (uintptr_t) ::mmap(addr, size, prot, |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2523 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB, |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2524 -1, 0); |
3885 | 2525 if (res != (uintptr_t) MAP_FAILED) { |
2526 if (UseNUMAInterleaving) { | |
2527 numa_make_global(addr, size); | |
2528 } | |
2529 return true; | |
2530 } | |
3913
27702f012017
7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents:
3887
diff
changeset
|
2531 // Fall through and try to use small pages |
27702f012017
7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents:
3887
diff
changeset
|
2532 } |
27702f012017
7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents:
3887
diff
changeset
|
2533 |
27702f012017
7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents:
3887
diff
changeset
|
2534 if (commit_memory(addr, size, exec)) { |
27702f012017
7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents:
3887
diff
changeset
|
2535 realign_memory(addr, size, alignment_hint); |
27702f012017
7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents:
3887
diff
changeset
|
2536 return true; |
27702f012017
7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents:
3887
diff
changeset
|
2537 } |
27702f012017
7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents:
3887
diff
changeset
|
2538 return false; |
0 | 2539 } |
2540 | |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2541 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2542 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2543 // We don't check the return value: madvise(MADV_HUGEPAGE) may not |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2544 // be supported or the memory may already be backed by huge pages. |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2545 ::madvise(addr, bytes, MADV_HUGEPAGE); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2546 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2547 } |
141 | 2548 |
4734
20bfb6d15a94
7124829: NUMA: memory leak on Linux with large pages
iveresov
parents:
4712
diff
changeset
|
2549 void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) { |
20bfb6d15a94
7124829: NUMA: memory leak on Linux with large pages
iveresov
parents:
4712
diff
changeset
|
2550 commit_memory(addr, bytes, alignment_hint, false); |
141 | 2551 } |
2552 | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2553 void os::numa_make_global(char *addr, size_t bytes) { |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2554 Linux::numa_interleave_memory(addr, bytes); |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2555 } |
141 | 2556 |
2557 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { | |
2558 Linux::numa_tonode_memory(addr, bytes, lgrp_hint); | |
2559 } | |
2560 | |
2561 bool os::numa_topology_changed() { return false; } | |
2562 | |
2563 size_t os::numa_get_groups_num() { | |
2564 int max_node = Linux::numa_max_node(); | |
2565 return max_node > 0 ? max_node + 1 : 1; | |
2566 } | |
2567 | |
2568 int os::numa_get_group_id() { | |
2569 int cpu_id = Linux::sched_getcpu(); | |
2570 if (cpu_id != -1) { | |
2571 int lgrp_id = Linux::get_node_by_cpu(cpu_id); | |
2572 if (lgrp_id != -1) { | |
2573 return lgrp_id; | |
2574 } | |
0 | 2575 } |
2576 return 0; | |
2577 } | |
2578 | |
141 | 2579 size_t os::numa_get_leaf_groups(int *ids, size_t size) { |
2580 for (size_t i = 0; i < size; i++) { | |
2581 ids[i] = i; | |
2582 } | |
2583 return size; | |
2584 } | |
2585 | |
0 | 2586 bool os::get_page_info(char *start, page_info* info) { |
2587 return false; | |
2588 } | |
2589 | |
2590 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { | |
2591 return end; | |
2592 } | |
2593 | |
3826 | 2594 |
2595 int os::Linux::sched_getcpu_syscall(void) { | |
2596 unsigned int cpu; | |
2597 int retval = -1; | |
2598 | |
2599 #if defined(IA32) | |
3887
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2600 # ifndef SYS_getcpu |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2601 # define SYS_getcpu 318 |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2602 # endif |
3826 | 2603 retval = syscall(SYS_getcpu, &cpu, NULL, NULL); |
2604 #elif defined(AMD64) | |
3887
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2605 // Unfortunately we have to bring all these macros here from vsyscall.h |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2606 // to be able to compile on old linuxes. |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2607 # define __NR_vgetcpu 2 |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2608 # define VSYSCALL_START (-10UL << 20) |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2609 # define VSYSCALL_SIZE 1024 |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2610 # define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr)) |
3826 | 2611 typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache); |
2612 vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu); | |
2613 retval = vgetcpu(&cpu, NULL, NULL); | |
2614 #endif | |
2615 | |
2616 return (retval == -1) ? retval : cpu; | |
2617 } | |
2618 | |
2191 | 2619 // Something to do with the numa-aware allocator needs these symbols |
2620 extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { } | |
2621 extern "C" JNIEXPORT void numa_error(char *where) { } | |
2622 extern "C" JNIEXPORT int fork1() { return fork(); } | |
141 | 2623 |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2624 |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2625 // If we are running with libnuma version > 2, then we should |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2626 // be trying to use symbols with versions 1.1 |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2627 // If we are running with earlier version, which did not have symbol versions, |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2628 // we should use the base version. |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2629 void* os::Linux::libnuma_dlsym(void* handle, const char *name) { |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2630 void *f = dlvsym(handle, name, "libnuma_1.1"); |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2631 if (f == NULL) { |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2632 f = dlsym(handle, name); |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2633 } |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2634 return f; |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2635 } |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2636 |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2637 bool os::Linux::libnuma_init() { |
141 | 2638 // sched_getcpu() should be in libc. |
2639 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, | |
2640 dlsym(RTLD_DEFAULT, "sched_getcpu"))); | |
2641 | |
3826 | 2642 // If it's not, try a direct syscall. |
2643 if (sched_getcpu() == -1) | |
2644 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, (void*)&sched_getcpu_syscall)); | |
2645 | |
141 | 2646 if (sched_getcpu() != -1) { // Does it work? |
267
9d6a3a6891f8
6720130: NUMA allocator: The linux version should search for libnuma.so.1
iveresov
parents:
199
diff
changeset
|
2647 void *handle = dlopen("libnuma.so.1", RTLD_LAZY); |
141 | 2648 if (handle != NULL) { |
2649 set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t, | |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2650 libnuma_dlsym(handle, "numa_node_to_cpus"))); |
141 | 2651 set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t, |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2652 libnuma_dlsym(handle, "numa_max_node"))); |
141 | 2653 set_numa_available(CAST_TO_FN_PTR(numa_available_func_t, |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2654 libnuma_dlsym(handle, "numa_available"))); |
141 | 2655 set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t, |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2656 libnuma_dlsym(handle, "numa_tonode_memory"))); |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2657 set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t, |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2658 libnuma_dlsym(handle, "numa_interleave_memory"))); |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2659 |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2660 |
141 | 2661 if (numa_available() != -1) { |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2662 set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes")); |
141 | 2663 // Create a cpu -> node mapping |
2664 _cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true); | |
2665 rebuild_cpu_to_node_map(); | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2666 return true; |
141 | 2667 } |
2668 } | |
2669 } | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2670 return false; |
141 | 2671 } |
2672 | |
2673 // rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id. | |
2674 // The table is later used in get_node_by_cpu(). | |
2675 void os::Linux::rebuild_cpu_to_node_map() { | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2676 const size_t NCPUS = 32768; // Since the buffer size computation is very obscure |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2677 // in libnuma (possible values are starting from 16, |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2678 // and continuing up with every other power of 2, but less |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2679 // than the maximum number of CPUs supported by kernel), and |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2680 // is a subject to change (in libnuma version 2 the requirements |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2681 // are more reasonable) we'll just hardcode the number they use |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2682 // in the library. |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2683 const size_t BitsPerCLong = sizeof(long) * CHAR_BIT; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2684 |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2685 size_t cpu_num = os::active_processor_count(); |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2686 size_t cpu_map_size = NCPUS / BitsPerCLong; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2687 size_t cpu_map_valid_size = |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2688 MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size); |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2689 |
141 | 2690 cpu_to_node()->clear(); |
2691 cpu_to_node()->at_grow(cpu_num - 1); | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2692 size_t node_num = numa_get_groups_num(); |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2693 |
141 | 2694 unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size); |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2695 for (size_t i = 0; i < node_num; i++) { |
141 | 2696 if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) { |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2697 for (size_t j = 0; j < cpu_map_valid_size; j++) { |
141 | 2698 if (cpu_map[j] != 0) { |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2699 for (size_t k = 0; k < BitsPerCLong; k++) { |
141 | 2700 if (cpu_map[j] & (1UL << k)) { |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2701 cpu_to_node()->at_put(j * BitsPerCLong + k, i); |
141 | 2702 } |
2703 } | |
2704 } | |
2705 } | |
2706 } | |
2707 } | |
2708 FREE_C_HEAP_ARRAY(unsigned long, cpu_map); | |
2709 } | |
2710 | |
2711 int os::Linux::get_node_by_cpu(int cpu_id) { | |
2712 if (cpu_to_node() != NULL && cpu_id >= 0 && cpu_id < cpu_to_node()->length()) { | |
2713 return cpu_to_node()->at(cpu_id); | |
2714 } | |
2715 return -1; | |
2716 } | |
2717 | |
2718 GrowableArray<int>* os::Linux::_cpu_to_node; | |
2719 os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu; | |
2720 os::Linux::numa_node_to_cpus_func_t os::Linux::_numa_node_to_cpus; | |
2721 os::Linux::numa_max_node_func_t os::Linux::_numa_max_node; | |
2722 os::Linux::numa_available_func_t os::Linux::_numa_available; | |
2723 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2724 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2725 unsigned long* os::Linux::_numa_all_nodes; |
141 | 2726 |
0 | 2727 bool os::uncommit_memory(char* addr, size_t size) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2728 uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE, |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2729 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2730 return res != (uintptr_t) MAP_FAILED; |
0 | 2731 } |
2732 | |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2733 // Linux uses a growable mapping for the stack, and if the mapping for |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2734 // the stack guard pages is not removed when we detach a thread the |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2735 // stack cannot grow beyond the pages where the stack guard was |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2736 // mapped. If at some point later in the process the stack expands to |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2737 // that point, the Linux kernel cannot expand the stack any further |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2738 // because the guard pages are in the way, and a segfault occurs. |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2739 // |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2740 // However, it's essential not to split the stack region by unmapping |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2741 // a region (leaving a hole) that's already part of the stack mapping, |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2742 // so if the stack mapping has already grown beyond the guard pages at |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2743 // the time we create them, we have to truncate the stack mapping. |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2744 // So, we need to know the extent of the stack mapping when |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2745 // create_stack_guard_pages() is called. |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2746 |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2747 // Find the bounds of the stack mapping. Return true for success. |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2748 // |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2749 // We only need this for stacks that are growable: at the time of |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2750 // writing thread stacks don't use growable mappings (i.e. those |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2751 // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2752 // only applies to the main thread. |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2753 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2754 static |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2755 bool get_stack_bounds(uintptr_t *bottom, uintptr_t *top) { |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2756 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2757 char buf[128]; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2758 int fd, sz; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2759 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2760 if ((fd = ::open("/proc/self/maps", O_RDONLY)) < 0) { |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2761 return false; |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2762 } |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2763 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2764 const char kw[] = "[stack]"; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2765 const int kwlen = sizeof(kw)-1; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2766 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2767 // Address part of /proc/self/maps couldn't be more than 128 bytes |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2768 while ((sz = os::get_line_chars(fd, buf, sizeof(buf))) > 0) { |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2769 if (sz > kwlen && ::memcmp(buf+sz-kwlen, kw, kwlen) == 0) { |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2770 // Extract addresses |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2771 if (sscanf(buf, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) { |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2772 uintptr_t sp = (uintptr_t) __builtin_frame_address(0); |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2773 if (sp >= *bottom && sp <= *top) { |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2774 ::close(fd); |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2775 return true; |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2776 } |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2777 } |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2778 } |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2779 } |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2780 |
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2781 ::close(fd); |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2782 return false; |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2783 } |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2784 |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
2785 |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2786 // If the (growable) stack mapping already extends beyond the point |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2787 // where we're going to put our guard pages, truncate the mapping at |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2788 // that point by munmap()ping it. This ensures that when we later |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2789 // munmap() the guard pages we don't leave a hole in the stack |
1750
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2790 // mapping. This only affects the main/initial thread, but guard |
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2791 // against future OS changes |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2792 bool os::create_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
|
2793 uintptr_t stack_extent, stack_base; |
1750
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2794 bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true); |
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2795 if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) { |
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2796 assert(os::Linux::is_initial_thread(), |
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2797 "growable stack in non-initial thread"); |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2798 if (stack_extent < (uintptr_t)addr) |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2799 ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent); |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2800 } |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2801 |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2802 return os::commit_memory(addr, size); |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2803 } |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2804 |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2805 // If this is a growable mapping, remove the guard pages entirely by |
1750
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2806 // munmap()ping them. If not, just call uncommit_memory(). This only |
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2807 // affects the main/initial thread, but guard against future OS changes |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2808 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
|
2809 uintptr_t stack_extent, stack_base; |
1750
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2810 bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true); |
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2811 if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) { |
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2812 assert(os::Linux::is_initial_thread(), |
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2813 "growable stack in non-initial thread"); |
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
2814 |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2815 return ::munmap(addr, size) == 0; |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2816 } |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2817 |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2818 return os::uncommit_memory(addr, size); |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2819 } |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
2820 |
0 | 2821 static address _highest_vm_reserved_address = NULL; |
2822 | |
2823 // If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory | |
2824 // at 'requested_addr'. If there are existing memory mappings at the same | |
2825 // location, however, they will be overwritten. If 'fixed' is false, | |
2826 // 'requested_addr' is only treated as a hint, the return value may or | |
2827 // may not start from the requested address. Unlike Linux mmap(), this | |
2828 // function returns NULL to indicate failure. | |
2829 static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) { | |
2830 char * addr; | |
2831 int flags; | |
2832 | |
2833 flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS; | |
2834 if (fixed) { | |
2835 assert((uintptr_t)requested_addr % os::Linux::page_size() == 0, "unaligned address"); | |
2836 flags |= MAP_FIXED; | |
2837 } | |
2838 | |
656 | 2839 // Map uncommitted pages PROT_READ and PROT_WRITE, change access |
2840 // to PROT_EXEC if executable when we commit the page. | |
2841 addr = (char*)::mmap(requested_addr, bytes, PROT_READ|PROT_WRITE, | |
0 | 2842 flags, -1, 0); |
2843 | |
2844 if (addr != MAP_FAILED) { | |
2845 // anon_mmap() should only get called during VM initialization, | |
2846 // don't need lock (actually we can skip locking even it can be called | |
2847 // from multiple threads, because _highest_vm_reserved_address is just a | |
2848 // hint about the upper limit of non-stack memory regions.) | |
2849 if ((address)addr + bytes > _highest_vm_reserved_address) { | |
2850 _highest_vm_reserved_address = (address)addr + bytes; | |
2851 } | |
2852 } | |
2853 | |
2854 return addr == MAP_FAILED ? NULL : addr; | |
2855 } | |
2856 | |
2857 // Don't update _highest_vm_reserved_address, because there might be memory | |
2858 // regions above addr + size. If so, releasing a memory region only creates | |
2859 // a hole in the address space, it doesn't help prevent heap-stack collision. | |
2860 // | |
2861 static int anon_munmap(char * addr, size_t size) { | |
2862 return ::munmap(addr, size) == 0; | |
2863 } | |
2864 | |
2865 char* os::reserve_memory(size_t bytes, char* requested_addr, | |
2866 size_t alignment_hint) { | |
2867 return anon_mmap(requested_addr, bytes, (requested_addr != NULL)); | |
2868 } | |
2869 | |
2870 bool os::release_memory(char* addr, size_t size) { | |
2871 return anon_munmap(addr, size); | |
2872 } | |
2873 | |
2874 static address highest_vm_reserved_address() { | |
2875 return _highest_vm_reserved_address; | |
2876 } | |
2877 | |
2878 static bool linux_mprotect(char* addr, size_t size, int prot) { | |
2879 // Linux wants the mprotect address argument to be page aligned. | |
2880 char* bottom = (char*)align_size_down((intptr_t)addr, os::Linux::page_size()); | |
2881 | |
2882 // According to SUSv3, mprotect() should only be used with mappings | |
2883 // established by mmap(), and mmap() always maps whole pages. Unaligned | |
2884 // 'addr' likely indicates problem in the VM (e.g. trying to change | |
2885 // protection of malloc'ed or statically allocated memory). Check the | |
2886 // caller if you hit this assert. | |
2887 assert(addr == bottom, "sanity check"); | |
2888 | |
2889 size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Linux::page_size()); | |
2890 return ::mprotect(bottom, size, prot) == 0; | |
2891 } | |
2892 | |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2893 // Set protections specified |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2894 bool os::protect_memory(char* addr, size_t bytes, ProtType prot, |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2895 bool is_committed) { |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2896 unsigned int p = 0; |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2897 switch (prot) { |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2898 case MEM_PROT_NONE: p = PROT_NONE; break; |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2899 case MEM_PROT_READ: p = PROT_READ; break; |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2900 case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break; |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2901 case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break; |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2902 default: |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2903 ShouldNotReachHere(); |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2904 } |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2905 // is_committed is unused. |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
2906 return linux_mprotect(addr, bytes, p); |
0 | 2907 } |
2908 | |
2909 bool os::guard_memory(char* addr, size_t size) { | |
2910 return linux_mprotect(addr, size, PROT_NONE); | |
2911 } | |
2912 | |
2913 bool os::unguard_memory(char* addr, size_t size) { | |
477
24fda36852ce
6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents:
462
diff
changeset
|
2914 return linux_mprotect(addr, size, PROT_READ|PROT_WRITE); |
0 | 2915 } |
2916 | |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2917 bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2918 bool result = false; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2919 void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE, |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2920 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB, |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2921 -1, 0); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2922 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2923 if (p != (void *) -1) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2924 // We don't know if this really is a huge page or not. |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2925 FILE *fp = fopen("/proc/self/maps", "r"); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2926 if (fp) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2927 while (!feof(fp)) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2928 char chars[257]; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2929 long x = 0; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2930 if (fgets(chars, sizeof(chars), fp)) { |
3358 | 2931 if (sscanf(chars, "%lx-%*x", &x) == 1 |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2932 && x == (long)p) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2933 if (strstr (chars, "hugepage")) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2934 result = true; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2935 break; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2936 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2937 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2938 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2939 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2940 fclose(fp); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2941 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2942 munmap (p, page_size); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2943 if (result) |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2944 return true; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2945 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2946 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2947 if (warn) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2948 warning("HugeTLBFS is not supported by the operating system."); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2949 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2950 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2951 return result; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2952 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2953 |
2204
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2954 /* |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2955 * Set the coredump_filter bits to include largepages in core dump (bit 6) |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2956 * |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2957 * From the coredump_filter documentation: |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2958 * |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2959 * - (bit 0) anonymous private memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2960 * - (bit 1) anonymous shared memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2961 * - (bit 2) file-backed private memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2962 * - (bit 3) file-backed shared memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2963 * - (bit 4) ELF header pages in file-backed private memory areas (it is |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2964 * effective only if the bit 2 is cleared) |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2965 * - (bit 5) hugetlb private memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2966 * - (bit 6) hugetlb shared memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2967 */ |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2968 static void set_coredump_filter(void) { |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2969 FILE *f; |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2970 long cdm; |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2971 |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2972 if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) { |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2973 return; |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2974 } |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2975 |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2976 if (fscanf(f, "%lx", &cdm) != 1) { |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2977 fclose(f); |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2978 return; |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2979 } |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2980 |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2981 rewind(f); |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2982 |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2983 if ((cdm & LARGEPAGES_BIT) == 0) { |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2984 cdm |= LARGEPAGES_BIT; |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2985 fprintf(f, "%#lx", cdm); |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2986 } |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2987 |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2988 fclose(f); |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2989 } |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
2990 |
0 | 2991 // Large page support |
2992 | |
2993 static size_t _large_page_size = 0; | |
2994 | |
3318
188c9a5d6a6d
7040485: Use transparent huge page on linux by default
iveresov
parents:
3292
diff
changeset
|
2995 void os::large_page_init() { |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2996 if (!UseLargePages) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2997 UseHugeTLBFS = false; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2998 UseSHM = false; |
3318
188c9a5d6a6d
7040485: Use transparent huge page on linux by default
iveresov
parents:
3292
diff
changeset
|
2999 return; |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3000 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3001 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3002 if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) { |
3318
188c9a5d6a6d
7040485: Use transparent huge page on linux by default
iveresov
parents:
3292
diff
changeset
|
3003 // If UseLargePages is specified on the command line try both methods, |
188c9a5d6a6d
7040485: Use transparent huge page on linux by default
iveresov
parents:
3292
diff
changeset
|
3004 // if it's default, then try only HugeTLBFS. |
188c9a5d6a6d
7040485: Use transparent huge page on linux by default
iveresov
parents:
3292
diff
changeset
|
3005 if (FLAG_IS_DEFAULT(UseLargePages)) { |
188c9a5d6a6d
7040485: Use transparent huge page on linux by default
iveresov
parents:
3292
diff
changeset
|
3006 UseHugeTLBFS = true; |
188c9a5d6a6d
7040485: Use transparent huge page on linux by default
iveresov
parents:
3292
diff
changeset
|
3007 } else { |
188c9a5d6a6d
7040485: Use transparent huge page on linux by default
iveresov
parents:
3292
diff
changeset
|
3008 UseHugeTLBFS = UseSHM = true; |
188c9a5d6a6d
7040485: Use transparent huge page on linux by default
iveresov
parents:
3292
diff
changeset
|
3009 } |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3010 } |
0 | 3011 |
3012 if (LargePageSizeInBytes) { | |
3013 _large_page_size = LargePageSizeInBytes; | |
3014 } else { | |
3015 // large_page_size on Linux is used to round up heap size. x86 uses either | |
3016 // 2M or 4M page, depending on whether PAE (Physical Address Extensions) | |
3017 // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use | |
3018 // page as large as 256M. | |
3019 // | |
3020 // Here we try to figure out page size by parsing /proc/meminfo and looking | |
3021 // for a line with the following format: | |
3022 // Hugepagesize: 2048 kB | |
3023 // | |
3024 // If we can't determine the value (e.g. /proc is not mounted, or the text | |
3025 // format has been changed), we'll use the largest page size supported by | |
3026 // the processor. | |
3027 | |
1010 | 3028 #ifndef ZERO |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
3029 _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
3030 ARM_ONLY(2 * M) PPC_ONLY(4 * M); |
1010 | 3031 #endif // ZERO |
0 | 3032 |
3033 FILE *fp = fopen("/proc/meminfo", "r"); | |
3034 if (fp) { | |
3035 while (!feof(fp)) { | |
3036 int x = 0; | |
3037 char buf[16]; | |
3038 if (fscanf(fp, "Hugepagesize: %d", &x) == 1) { | |
3039 if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) { | |
3040 _large_page_size = x * K; | |
3041 break; | |
3042 } | |
3043 } else { | |
3044 // skip to next line | |
3045 for (;;) { | |
3046 int ch = fgetc(fp); | |
3047 if (ch == EOF || ch == (int)'\n') break; | |
3048 } | |
3049 } | |
3050 } | |
3051 fclose(fp); | |
3052 } | |
3053 } | |
3054 | |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3055 // print a warning if any large page related flag is specified on command line |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3056 bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3057 |
0 | 3058 const size_t default_page_size = (size_t)Linux::page_size(); |
3059 if (_large_page_size > default_page_size) { | |
3060 _page_sizes[0] = _large_page_size; | |
3061 _page_sizes[1] = default_page_size; | |
3062 _page_sizes[2] = 0; | |
3063 } | |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3064 UseHugeTLBFS = UseHugeTLBFS && |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3065 Linux::hugetlbfs_sanity_check(warn_on_failure, _large_page_size); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3066 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3067 if (UseHugeTLBFS) |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3068 UseSHM = false; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3069 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3070 UseLargePages = UseHugeTLBFS || UseSHM; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3071 |
2204
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3072 set_coredump_filter(); |
0 | 3073 } |
3074 | |
3075 #ifndef SHM_HUGETLB | |
3076 #define SHM_HUGETLB 04000 | |
3077 #endif | |
3078 | |
656 | 3079 char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) { |
3080 // "exec" is passed in but not used. Creating the shared image for | |
3081 // the code cache doesn't have an SHM_X executable permission to check. | |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3082 assert(UseLargePages && UseSHM, "only for SHM large pages"); |
0 | 3083 |
3084 key_t key = IPC_PRIVATE; | |
3085 char *addr; | |
3086 | |
3087 bool warn_on_failure = UseLargePages && | |
3088 (!FLAG_IS_DEFAULT(UseLargePages) || | |
3089 !FLAG_IS_DEFAULT(LargePageSizeInBytes) | |
3090 ); | |
3091 char msg[128]; | |
3092 | |
3093 // Create a large shared memory region to attach to based on size. | |
3094 // Currently, size is the total size of the heap | |
3095 int shmid = shmget(key, bytes, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W); | |
3096 if (shmid == -1) { | |
3097 // Possible reasons for shmget failure: | |
3098 // 1. shmmax is too small for Java heap. | |
3099 // > check shmmax value: cat /proc/sys/kernel/shmmax | |
3100 // > increase shmmax value: echo "0xffffffff" > /proc/sys/kernel/shmmax | |
3101 // 2. not enough large page memory. | |
3102 // > check available large pages: cat /proc/meminfo | |
3103 // > increase amount of large pages: | |
3104 // echo new_value > /proc/sys/vm/nr_hugepages | |
3105 // Note 1: different Linux may use different name for this property, | |
3106 // e.g. on Redhat AS-3 it is "hugetlb_pool". | |
3107 // Note 2: it's possible there's enough physical memory available but | |
3108 // they are so fragmented after a long run that they can't | |
3109 // coalesce into large pages. Try to reserve large pages when | |
3110 // the system is still "fresh". | |
3111 if (warn_on_failure) { | |
3112 jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno); | |
3113 warning(msg); | |
3114 } | |
3115 return NULL; | |
3116 } | |
3117 | |
3118 // attach to the region | |
1537
79bf863697eb
6951686: Using large pages on Linux prevents zero based compressed oops
kvn
parents:
1500
diff
changeset
|
3119 addr = (char*)shmat(shmid, req_addr, 0); |
0 | 3120 int err = errno; |
3121 | |
3122 // Remove shmid. If shmat() is successful, the actual shared memory segment | |
3123 // will be deleted when it's detached by shmdt() or when the process | |
3124 // terminates. If shmat() is not successful this will remove the shared | |
3125 // segment immediately. | |
3126 shmctl(shmid, IPC_RMID, NULL); | |
3127 | |
3128 if ((intptr_t)addr == -1) { | |
3129 if (warn_on_failure) { | |
3130 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); | |
3131 warning(msg); | |
3132 } | |
3133 return NULL; | |
3134 } | |
3135 | |
3885 | 3136 if ((addr != NULL) && UseNUMAInterleaving) { |
3137 numa_make_global(addr, bytes); | |
3138 } | |
3139 | |
0 | 3140 return addr; |
3141 } | |
3142 | |
3143 bool os::release_memory_special(char* base, size_t bytes) { | |
3144 // detaching the SHM segment will also delete it, see reserve_memory_special() | |
3145 int rslt = shmdt(base); | |
3146 return rslt == 0; | |
3147 } | |
3148 | |
3149 size_t os::large_page_size() { | |
3150 return _large_page_size; | |
3151 } | |
3152 | |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3153 // HugeTLBFS allows application to commit large page memory on demand; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3154 // with SysV SHM the entire memory region must be allocated as shared |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3155 // memory. |
0 | 3156 bool os::can_commit_large_page_memory() { |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3157 return UseHugeTLBFS; |
0 | 3158 } |
3159 | |
79
82db0859acbe
6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents:
62
diff
changeset
|
3160 bool os::can_execute_large_page_memory() { |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3161 return UseHugeTLBFS; |
79
82db0859acbe
6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents:
62
diff
changeset
|
3162 } |
82db0859acbe
6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents:
62
diff
changeset
|
3163 |
0 | 3164 // Reserve memory at an arbitrary address, only if that area is |
3165 // available (and not reserved for something else). | |
3166 | |
3167 char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) { | |
3168 const int max_tries = 10; | |
3169 char* base[max_tries]; | |
3170 size_t size[max_tries]; | |
3171 const size_t gap = 0x000000; | |
3172 | |
3173 // Assert only that the size is a multiple of the page size, since | |
3174 // that's all that mmap requires, and since that's all we really know | |
3175 // about at this low abstraction level. If we need higher alignment, | |
3176 // we can either pass an alignment to this method or verify alignment | |
3177 // in one of the methods further up the call chain. See bug 5044738. | |
3178 assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block"); | |
3179 | |
3180 // Repeatedly allocate blocks until the block is allocated at the | |
3181 // right spot. Give up after max_tries. Note that reserve_memory() will | |
3182 // automatically update _highest_vm_reserved_address if the call is | |
3183 // successful. The variable tracks the highest memory address every reserved | |
3184 // by JVM. It is used to detect heap-stack collision if running with | |
3185 // fixed-stack LinuxThreads. Because here we may attempt to reserve more | |
3186 // space than needed, it could confuse the collision detecting code. To | |
3187 // solve the problem, save current _highest_vm_reserved_address and | |
3188 // calculate the correct value before return. | |
3189 address old_highest = _highest_vm_reserved_address; | |
3190 | |
3191 // Linux mmap allows caller to pass an address as hint; give it a try first, | |
3192 // if kernel honors the hint then we can return immediately. | |
3193 char * addr = anon_mmap(requested_addr, bytes, false); | |
3194 if (addr == requested_addr) { | |
3195 return requested_addr; | |
3196 } | |
3197 | |
3198 if (addr != NULL) { | |
3199 // mmap() is successful but it fails to reserve at the requested address | |
3200 anon_munmap(addr, bytes); | |
3201 } | |
3202 | |
3203 int i; | |
3204 for (i = 0; i < max_tries; ++i) { | |
3205 base[i] = reserve_memory(bytes); | |
3206 | |
3207 if (base[i] != NULL) { | |
3208 // Is this the block we wanted? | |
3209 if (base[i] == requested_addr) { | |
3210 size[i] = bytes; | |
3211 break; | |
3212 } | |
3213 | |
3214 // Does this overlap the block we wanted? Give back the overlapped | |
3215 // parts and try again. | |
3216 | |
3217 size_t top_overlap = requested_addr + (bytes + gap) - base[i]; | |
3218 if (top_overlap >= 0 && top_overlap < bytes) { | |
3219 unmap_memory(base[i], top_overlap); | |
3220 base[i] += top_overlap; | |
3221 size[i] = bytes - top_overlap; | |
3222 } else { | |
3223 size_t bottom_overlap = base[i] + bytes - requested_addr; | |
3224 if (bottom_overlap >= 0 && bottom_overlap < bytes) { | |
3225 unmap_memory(requested_addr, bottom_overlap); | |
3226 size[i] = bytes - bottom_overlap; | |
3227 } else { | |
3228 size[i] = bytes; | |
3229 } | |
3230 } | |
3231 } | |
3232 } | |
3233 | |
3234 // Give back the unused reserved pieces. | |
3235 | |
3236 for (int j = 0; j < i; ++j) { | |
3237 if (base[j] != NULL) { | |
3238 unmap_memory(base[j], size[j]); | |
3239 } | |
3240 } | |
3241 | |
3242 if (i < max_tries) { | |
3243 _highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes); | |
3244 return requested_addr; | |
3245 } else { | |
3246 _highest_vm_reserved_address = old_highest; | |
3247 return NULL; | |
3248 } | |
3249 } | |
3250 | |
3251 size_t os::read(int fd, void *buf, unsigned int nBytes) { | |
3252 return ::read(fd, buf, nBytes); | |
3253 } | |
3254 | |
3255 // TODO-FIXME: reconcile Solaris' os::sleep with the linux variation. | |
3256 // Solaris uses poll(), linux uses park(). | |
3257 // Poll() is likely a better choice, assuming that Thread.interrupt() | |
3258 // generates a SIGUSRx signal. Note that SIGUSR1 can interfere with | |
3259 // SIGSEGV, see 4355769. | |
3260 | |
3261 int os::sleep(Thread* thread, jlong millis, bool interruptible) { | |
3262 assert(thread == Thread::current(), "thread consistency check"); | |
3263 | |
3264 ParkEvent * const slp = thread->_SleepEvent ; | |
3265 slp->reset() ; | |
3266 OrderAccess::fence() ; | |
3267 | |
3268 if (interruptible) { | |
3269 jlong prevtime = javaTimeNanos(); | |
3270 | |
3271 for (;;) { | |
3272 if (os::is_interrupted(thread, true)) { | |
3273 return OS_INTRPT; | |
3274 } | |
3275 | |
3276 jlong newtime = javaTimeNanos(); | |
3277 | |
3278 if (newtime - prevtime < 0) { | |
3279 // time moving backwards, should only happen if no monotonic clock | |
3280 // not a guarantee() because JVM should not abort on kernel/glibc bugs | |
3281 assert(!Linux::supports_monotonic_clock(), "time moving backwards"); | |
3282 } else { | |
4712
e7dead7e90af
7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents:
4082
diff
changeset
|
3283 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; |
0 | 3284 } |
3285 | |
3286 if(millis <= 0) { | |
3287 return OS_OK; | |
3288 } | |
3289 | |
3290 prevtime = newtime; | |
3291 | |
3292 { | |
3293 assert(thread->is_Java_thread(), "sanity check"); | |
3294 JavaThread *jt = (JavaThread *) thread; | |
3295 ThreadBlockInVM tbivm(jt); | |
3296 OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); | |
3297 | |
3298 jt->set_suspend_equivalent(); | |
3299 // cleared by handle_special_suspend_equivalent_condition() or | |
3300 // java_suspend_self() via check_and_wait_while_suspended() | |
3301 | |
3302 slp->park(millis); | |
3303 | |
3304 // were we externally suspended while we were waiting? | |
3305 jt->check_and_wait_while_suspended(); | |
3306 } | |
3307 } | |
3308 } else { | |
3309 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); | |
3310 jlong prevtime = javaTimeNanos(); | |
3311 | |
3312 for (;;) { | |
3313 // It'd be nice to avoid the back-to-back javaTimeNanos() calls on | |
3314 // the 1st iteration ... | |
3315 jlong newtime = javaTimeNanos(); | |
3316 | |
3317 if (newtime - prevtime < 0) { | |
3318 // time moving backwards, should only happen if no monotonic clock | |
3319 // not a guarantee() because JVM should not abort on kernel/glibc bugs | |
3320 assert(!Linux::supports_monotonic_clock(), "time moving backwards"); | |
3321 } else { | |
4712
e7dead7e90af
7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents:
4082
diff
changeset
|
3322 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; |
0 | 3323 } |
3324 | |
3325 if(millis <= 0) break ; | |
3326 | |
3327 prevtime = newtime; | |
3328 slp->park(millis); | |
3329 } | |
3330 return OS_OK ; | |
3331 } | |
3332 } | |
3333 | |
3334 int os::naked_sleep() { | |
3335 // %% make the sleep time an integer flag. for now use 1 millisec. | |
3336 return os::sleep(Thread::current(), 1, false); | |
3337 } | |
3338 | |
3339 // Sleep forever; naked call to OS-specific sleep; use with CAUTION | |
3340 void os::infinite_sleep() { | |
3341 while (true) { // sleep forever ... | |
3342 ::sleep(100); // ... 100 seconds at a time | |
3343 } | |
3344 } | |
3345 | |
3346 // Used to convert frequent JVM_Yield() to nops | |
3347 bool os::dont_yield() { | |
3348 return DontYieldALot; | |
3349 } | |
3350 | |
3351 void os::yield() { | |
3352 sched_yield(); | |
3353 } | |
3354 | |
3355 os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;} | |
3356 | |
3357 void os::yield_all(int attempts) { | |
3358 // Yields to all threads, including threads with lower priorities | |
3359 // Threads on Linux are all with same priority. The Solaris style | |
3360 // os::yield_all() with nanosleep(1ms) is not necessary. | |
3361 sched_yield(); | |
3362 } | |
3363 | |
3364 // Called from the tight loops to possibly influence time-sharing heuristics | |
3365 void os::loop_breaker(int attempts) { | |
3366 os::yield_all(attempts); | |
3367 } | |
3368 | |
3369 //////////////////////////////////////////////////////////////////////////////// | |
3370 // thread priority support | |
3371 | |
3372 // Note: Normal Linux applications are run with SCHED_OTHER policy. SCHED_OTHER | |
3373 // only supports dynamic priority, static priority must be zero. For real-time | |
3374 // applications, Linux supports SCHED_RR which allows static priority (1-99). | |
3375 // However, for large multi-threaded applications, SCHED_RR is not only slower | |
3376 // than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out | |
3377 // of 5 runs - Sep 2005). | |
3378 // | |
3379 // The following code actually changes the niceness of kernel-thread/LWP. It | |
3380 // has an assumption that setpriority() only modifies one kernel-thread/LWP, | |
3381 // not the entire user process, and user level threads are 1:1 mapped to kernel | |
3382 // threads. It has always been the case, but could change in the future. For | |
3383 // this reason, the code should not be used as default (ThreadPriorityPolicy=0). | |
3384 // It is only used when ThreadPriorityPolicy=1 and requires root privilege. | |
3385 | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3386 int os::java_to_os_priority[CriticalPriority + 1] = { |
0 | 3387 19, // 0 Entry should never be used |
3388 | |
3389 4, // 1 MinPriority | |
3390 3, // 2 | |
3391 2, // 3 | |
3392 | |
3393 1, // 4 | |
3394 0, // 5 NormPriority | |
3395 -1, // 6 | |
3396 | |
3397 -2, // 7 | |
3398 -3, // 8 | |
3399 -4, // 9 NearMaxPriority | |
3400 | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3401 -5, // 10 MaxPriority |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3402 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3403 -5 // 11 CriticalPriority |
0 | 3404 }; |
3405 | |
3406 static int prio_init() { | |
3407 if (ThreadPriorityPolicy == 1) { | |
3408 // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1 | |
3409 // if effective uid is not root. Perhaps, a more elegant way of doing | |
3410 // this is to test CAP_SYS_NICE capability, but that will require libcap.so | |
3411 if (geteuid() != 0) { | |
3412 if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) { | |
3413 warning("-XX:ThreadPriorityPolicy requires root privilege on Linux"); | |
3414 } | |
3415 ThreadPriorityPolicy = 0; | |
3416 } | |
3417 } | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3418 if (UseCriticalJavaThreadPriority) { |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3419 os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority]; |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3420 } |
0 | 3421 return 0; |
3422 } | |
3423 | |
3424 OSReturn os::set_native_priority(Thread* thread, int newpri) { | |
3425 if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK; | |
3426 | |
3427 int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri); | |
3428 return (ret == 0) ? OS_OK : OS_ERR; | |
3429 } | |
3430 | |
3431 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { | |
3432 if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) { | |
3433 *priority_ptr = java_to_os_priority[NormPriority]; | |
3434 return OS_OK; | |
3435 } | |
3436 | |
3437 errno = 0; | |
3438 *priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id()); | |
3439 return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR); | |
3440 } | |
3441 | |
3442 // Hint to the underlying OS that a task switch would not be good. | |
3443 // Void return because it's a hint and can fail. | |
3444 void os::hint_no_preempt() {} | |
3445 | |
3446 //////////////////////////////////////////////////////////////////////////////// | |
3447 // suspend/resume support | |
3448 | |
3449 // the low-level signal-based suspend/resume support is a remnant from the | |
3450 // old VM-suspension that used to be for java-suspension, safepoints etc, | |
3451 // within hotspot. Now there is a single use-case for this: | |
3452 // - calling get_thread_pc() on the VMThread by the flat-profiler task | |
3453 // that runs in the watcher thread. | |
3454 // The remaining code is greatly simplified from the more general suspension | |
3455 // code that used to be used. | |
3456 // | |
3457 // The protocol is quite simple: | |
3458 // - suspend: | |
3459 // - sends a signal to the target thread | |
3460 // - polls the suspend state of the osthread using a yield loop | |
3461 // - target thread signal handler (SR_handler) sets suspend state | |
3462 // and blocks in sigsuspend until continued | |
3463 // - resume: | |
3464 // - sets target osthread state to continue | |
3465 // - sends signal to end the sigsuspend loop in the SR_handler | |
3466 // | |
3467 // Note that the SR_lock plays no role in this suspend/resume protocol. | |
3468 // | |
3469 | |
3470 static void resume_clear_context(OSThread *osthread) { | |
3471 osthread->set_ucontext(NULL); | |
3472 osthread->set_siginfo(NULL); | |
3473 | |
3474 // notify the suspend action is completed, we have now resumed | |
3475 osthread->sr.clear_suspended(); | |
3476 } | |
3477 | |
3478 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) { | |
3479 osthread->set_ucontext(context); | |
3480 osthread->set_siginfo(siginfo); | |
3481 } | |
3482 | |
3483 // | |
3484 // Handler function invoked when a thread's execution is suspended or | |
3485 // resumed. We have to be careful that only async-safe functions are | |
3486 // called here (Note: most pthread functions are not async safe and | |
3487 // should be avoided.) | |
3488 // | |
3489 // Note: sigwait() is a more natural fit than sigsuspend() from an | |
3490 // interface point of view, but sigwait() prevents the signal hander | |
3491 // from being run. libpthread would get very confused by not having | |
3492 // its signal handlers run and prevents sigwait()'s use with the | |
3493 // mutex granting granting signal. | |
3494 // | |
3495 // Currently only ever called on the VMThread | |
3496 // | |
3497 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { | |
3498 // Save and restore errno to avoid confusing native code with EINTR | |
3499 // after sigsuspend. | |
3500 int old_errno = errno; | |
3501 | |
3502 Thread* thread = Thread::current(); | |
3503 OSThread* osthread = thread->osthread(); | |
3504 assert(thread->is_VM_thread(), "Must be VMThread"); | |
3505 // read current suspend action | |
3506 int action = osthread->sr.suspend_action(); | |
3507 if (action == SR_SUSPEND) { | |
3508 suspend_save_context(osthread, siginfo, context); | |
3509 | |
3510 // Notify the suspend action is about to be completed. do_suspend() | |
3511 // waits until SR_SUSPENDED is set and then returns. We will wait | |
3512 // here for a resume signal and that completes the suspend-other | |
3513 // action. do_suspend/do_resume is always called as a pair from | |
3514 // the same thread - so there are no races | |
3515 | |
3516 // notify the caller | |
3517 osthread->sr.set_suspended(); | |
3518 | |
3519 sigset_t suspend_set; // signals for sigsuspend() | |
3520 | |
3521 // get current set of blocked signals and unblock resume signal | |
3522 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); | |
3523 sigdelset(&suspend_set, SR_signum); | |
3524 | |
3525 // wait here until we are resumed | |
3526 do { | |
3527 sigsuspend(&suspend_set); | |
3528 // ignore all returns until we get a resume signal | |
3529 } while (osthread->sr.suspend_action() != SR_CONTINUE); | |
3530 | |
3531 resume_clear_context(osthread); | |
3532 | |
3533 } else { | |
3534 assert(action == SR_CONTINUE, "unexpected sr action"); | |
3535 // nothing special to do - just leave the handler | |
3536 } | |
3537 | |
3538 errno = old_errno; | |
3539 } | |
3540 | |
3541 | |
3542 static int SR_initialize() { | |
3543 struct sigaction act; | |
3544 char *s; | |
3545 /* Get signal number to use for suspend/resume */ | |
3546 if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { | |
3547 int sig = ::strtol(s, 0, 10); | |
3548 if (sig > 0 || sig < _NSIG) { | |
3549 SR_signum = sig; | |
3550 } | |
3551 } | |
3552 | |
3553 assert(SR_signum > SIGSEGV && SR_signum > SIGBUS, | |
3554 "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769"); | |
3555 | |
3556 sigemptyset(&SR_sigset); | |
3557 sigaddset(&SR_sigset, SR_signum); | |
3558 | |
3559 /* Set up signal handler for suspend/resume */ | |
3560 act.sa_flags = SA_RESTART|SA_SIGINFO; | |
3561 act.sa_handler = (void (*)(int)) SR_handler; | |
3562 | |
3563 // SR_signum is blocked by default. | |
3564 // 4528190 - We also need to block pthread restart signal (32 on all | |
3565 // supported Linux platforms). Note that LinuxThreads need to block | |
3566 // this signal for all threads to work properly. So we don't have | |
3567 // to use hard-coded signal number when setting up the mask. | |
3568 pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask); | |
3569 | |
3570 if (sigaction(SR_signum, &act, 0) == -1) { | |
3571 return -1; | |
3572 } | |
3573 | |
3574 // Save signal flag | |
3575 os::Linux::set_our_sigflags(SR_signum, act.sa_flags); | |
3576 return 0; | |
3577 } | |
3578 | |
3579 static int SR_finalize() { | |
3580 return 0; | |
3581 } | |
3582 | |
3583 | |
3584 // returns true on success and false on error - really an error is fatal | |
3585 // but this seems the normal response to library errors | |
3586 static bool do_suspend(OSThread* osthread) { | |
3587 // mark as suspended and send signal | |
3588 osthread->sr.set_suspend_action(SR_SUSPEND); | |
3589 int status = pthread_kill(osthread->pthread_id(), SR_signum); | |
3590 assert_status(status == 0, status, "pthread_kill"); | |
3591 | |
3592 // check status and wait until notified of suspension | |
3593 if (status == 0) { | |
3594 for (int i = 0; !osthread->sr.is_suspended(); i++) { | |
3595 os::yield_all(i); | |
3596 } | |
3597 osthread->sr.set_suspend_action(SR_NONE); | |
3598 return true; | |
3599 } | |
3600 else { | |
3601 osthread->sr.set_suspend_action(SR_NONE); | |
3602 return false; | |
3603 } | |
3604 } | |
3605 | |
3606 static void do_resume(OSThread* osthread) { | |
3607 assert(osthread->sr.is_suspended(), "thread should be suspended"); | |
3608 osthread->sr.set_suspend_action(SR_CONTINUE); | |
3609 | |
3610 int status = pthread_kill(osthread->pthread_id(), SR_signum); | |
3611 assert_status(status == 0, status, "pthread_kill"); | |
3612 // check status and wait unit notified of resumption | |
3613 if (status == 0) { | |
3614 for (int i = 0; osthread->sr.is_suspended(); i++) { | |
3615 os::yield_all(i); | |
3616 } | |
3617 } | |
3618 osthread->sr.set_suspend_action(SR_NONE); | |
3619 } | |
3620 | |
3621 //////////////////////////////////////////////////////////////////////////////// | |
3622 // interrupt support | |
3623 | |
3624 void os::interrupt(Thread* thread) { | |
3625 assert(Thread::current() == thread || Threads_lock->owned_by_self(), | |
3626 "possibility of dangling Thread pointer"); | |
3627 | |
3628 OSThread* osthread = thread->osthread(); | |
3629 | |
3630 if (!osthread->interrupted()) { | |
3631 osthread->set_interrupted(true); | |
3632 // More than one thread can get here with the same value of osthread, | |
3633 // resulting in multiple notifications. We do, however, want the store | |
3634 // to interrupted() to be visible to other threads before we execute unpark(). | |
3635 OrderAccess::fence(); | |
3636 ParkEvent * const slp = thread->_SleepEvent ; | |
3637 if (slp != NULL) slp->unpark() ; | |
3638 } | |
3639 | |
3640 // For JSR166. Unpark even if interrupt status already was set | |
3641 if (thread->is_Java_thread()) | |
3642 ((JavaThread*)thread)->parker()->unpark(); | |
3643 | |
3644 ParkEvent * ev = thread->_ParkEvent ; | |
3645 if (ev != NULL) ev->unpark() ; | |
3646 | |
3647 } | |
3648 | |
3649 bool os::is_interrupted(Thread* thread, bool clear_interrupted) { | |
3650 assert(Thread::current() == thread || Threads_lock->owned_by_self(), | |
3651 "possibility of dangling Thread pointer"); | |
3652 | |
3653 OSThread* osthread = thread->osthread(); | |
3654 | |
3655 bool interrupted = osthread->interrupted(); | |
3656 | |
3657 if (interrupted && clear_interrupted) { | |
3658 osthread->set_interrupted(false); | |
3659 // consider thread->_SleepEvent->reset() ... optional optimization | |
3660 } | |
3661 | |
3662 return interrupted; | |
3663 } | |
3664 | |
3665 /////////////////////////////////////////////////////////////////////////////////// | |
3666 // signal handling (except suspend/resume) | |
3667 | |
3668 // This routine may be used by user applications as a "hook" to catch signals. | |
3669 // The user-defined signal handler must pass unrecognized signals to this | |
3670 // routine, and if it returns true (non-zero), then the signal handler must | |
3671 // return immediately. If the flag "abort_if_unrecognized" is true, then this | |
3672 // routine will never retun false (zero), but instead will execute a VM panic | |
3673 // routine kill the process. | |
3674 // | |
3675 // If this routine returns false, it is OK to call it again. This allows | |
3676 // the user-defined signal handler to perform checks either before or after | |
3677 // the VM performs its own checks. Naturally, the user code would be making | |
3678 // a serious error if it tried to handle an exception (such as a null check | |
3679 // or breakpoint) that the VM was generating for its own correct operation. | |
3680 // | |
3681 // This routine may recognize any of the following kinds of signals: | |
3682 // SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1. | |
3683 // It should be consulted by handlers for any of those signals. | |
3684 // | |
3685 // The caller of this routine must pass in the three arguments supplied | |
3686 // to the function referred to in the "sa_sigaction" (not the "sa_handler") | |
3687 // field of the structure passed to sigaction(). This routine assumes that | |
3688 // the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART. | |
3689 // | |
3690 // Note that the VM will print warnings if it detects conflicting signal | |
3691 // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers". | |
3692 // | |
2191 | 3693 extern "C" JNIEXPORT int |
0 | 3694 JVM_handle_linux_signal(int signo, siginfo_t* siginfo, |
3695 void* ucontext, int abort_if_unrecognized); | |
3696 | |
3697 void signalHandler(int sig, siginfo_t* info, void* uc) { | |
3698 assert(info != NULL && uc != NULL, "it must be old kernel"); | |
1942
00bc9eaf0e24
Support for -XX:+UseFastLocking flag. Fixed monitor enter XIR template for correct debug info at the runtime call.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1936
diff
changeset
|
3699 ResourceMark rm; |
1936
8d88c9ac9247
Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1867
diff
changeset
|
3700 if (TraceSignals) { |
8d88c9ac9247
Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1867
diff
changeset
|
3701 tty->print_cr(err_msg("signal received: code=%d errno=%d signo=%d thread=%s address=%x", info->si_code, info->si_errno, info->si_signo, Thread::current()->name(), info->si_addr)); |
8d88c9ac9247
Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1867
diff
changeset
|
3702 } |
0 | 3703 JVM_handle_linux_signal(sig, info, uc, true); |
1936
8d88c9ac9247
Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1867
diff
changeset
|
3704 if (TraceSignals) { |
8d88c9ac9247
Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1867
diff
changeset
|
3705 tty->print_cr("signal handled"); |
8d88c9ac9247
Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1867
diff
changeset
|
3706 } |
0 | 3707 } |
3708 | |
3709 | |
3710 // This boolean allows users to forward their own non-matching signals | |
3711 // to JVM_handle_linux_signal, harmlessly. | |
3712 bool os::Linux::signal_handlers_are_installed = false; | |
3713 | |
3714 // For signal-chaining | |
3715 struct sigaction os::Linux::sigact[MAXSIGNUM]; | |
3716 unsigned int os::Linux::sigs = 0; | |
3717 bool os::Linux::libjsig_is_loaded = false; | |
3718 typedef struct sigaction *(*get_signal_t)(int); | |
3719 get_signal_t os::Linux::get_signal_action = NULL; | |
3720 | |
3721 struct sigaction* os::Linux::get_chained_signal_action(int sig) { | |
3722 struct sigaction *actp = NULL; | |
3723 | |
3724 if (libjsig_is_loaded) { | |
3725 // Retrieve the old signal handler from libjsig | |
3726 actp = (*get_signal_action)(sig); | |
3727 } | |
3728 if (actp == NULL) { | |
3729 // Retrieve the preinstalled signal handler from jvm | |
3730 actp = get_preinstalled_handler(sig); | |
3731 } | |
3732 | |
3733 return actp; | |
3734 } | |
3735 | |
3736 static bool call_chained_handler(struct sigaction *actp, int sig, | |
3737 siginfo_t *siginfo, void *context) { | |
3738 // Call the old signal handler | |
3739 if (actp->sa_handler == SIG_DFL) { | |
3740 // It's more reasonable to let jvm treat it as an unexpected exception | |
3741 // instead of taking the default action. | |
3742 return false; | |
3743 } else if (actp->sa_handler != SIG_IGN) { | |
3744 if ((actp->sa_flags & SA_NODEFER) == 0) { | |
3745 // automaticlly block the signal | |
3746 sigaddset(&(actp->sa_mask), sig); | |
3747 } | |
3748 | |
3749 sa_handler_t hand; | |
3750 sa_sigaction_t sa; | |
3751 bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0; | |
3752 // retrieve the chained handler | |
3753 if (siginfo_flag_set) { | |
3754 sa = actp->sa_sigaction; | |
3755 } else { | |
3756 hand = actp->sa_handler; | |
3757 } | |
3758 | |
3759 if ((actp->sa_flags & SA_RESETHAND) != 0) { | |
3760 actp->sa_handler = SIG_DFL; | |
3761 } | |
3762 | |
3763 // try to honor the signal mask | |
3764 sigset_t oset; | |
3765 pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset); | |
3766 | |
3767 // call into the chained handler | |
3768 if (siginfo_flag_set) { | |
3769 (*sa)(sig, siginfo, context); | |
3770 } else { | |
3771 (*hand)(sig); | |
3772 } | |
3773 | |
3774 // restore the signal mask | |
3775 pthread_sigmask(SIG_SETMASK, &oset, 0); | |
3776 } | |
3777 // Tell jvm's signal handler the signal is taken care of. | |
3778 return true; | |
3779 } | |
3780 | |
3781 bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) { | |
3782 bool chained = false; | |
3783 // signal-chaining | |
3784 if (UseSignalChaining) { | |
3785 struct sigaction *actp = get_chained_signal_action(sig); | |
3786 if (actp != NULL) { | |
3787 chained = call_chained_handler(actp, sig, siginfo, context); | |
3788 } | |
3789 } | |
3790 return chained; | |
3791 } | |
3792 | |
3793 struct sigaction* os::Linux::get_preinstalled_handler(int sig) { | |
3794 if ((( (unsigned int)1 << sig ) & sigs) != 0) { | |
3795 return &sigact[sig]; | |
3796 } | |
3797 return NULL; | |
3798 } | |
3799 | |
3800 void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) { | |
3801 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
3802 sigact[sig] = oldAct; | |
3803 sigs |= (unsigned int)1 << sig; | |
3804 } | |
3805 | |
3806 // for diagnostic | |
3807 int os::Linux::sigflags[MAXSIGNUM]; | |
3808 | |
3809 int os::Linux::get_our_sigflags(int sig) { | |
3810 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
3811 return sigflags[sig]; | |
3812 } | |
3813 | |
3814 void os::Linux::set_our_sigflags(int sig, int flags) { | |
3815 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
3816 sigflags[sig] = flags; | |
3817 } | |
3818 | |
3819 void os::Linux::set_signal_handler(int sig, bool set_installed) { | |
3820 // Check for overwrite. | |
3821 struct sigaction oldAct; | |
3822 sigaction(sig, (struct sigaction*)NULL, &oldAct); | |
3823 | |
3824 void* oldhand = oldAct.sa_sigaction | |
3825 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) | |
3826 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); | |
3827 if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) && | |
3828 oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) && | |
3829 oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) { | |
3830 if (AllowUserSignalHandlers || !set_installed) { | |
3831 // Do not overwrite; user takes responsibility to forward to us. | |
3832 return; | |
3833 } else if (UseSignalChaining) { | |
3834 // save the old handler in jvm | |
3835 save_preinstalled_handler(sig, oldAct); | |
3836 // libjsig also interposes the sigaction() call below and saves the | |
3837 // old sigaction on it own. | |
3838 } else { | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1353
diff
changeset
|
3839 fatal(err_msg("Encountered unexpected pre-existing sigaction handler " |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1353
diff
changeset
|
3840 "%#lx for signal %d.", (long)oldhand, sig)); |
0 | 3841 } |
3842 } | |
3843 | |
3844 struct sigaction sigAct; | |
3845 sigfillset(&(sigAct.sa_mask)); | |
3846 sigAct.sa_handler = SIG_DFL; | |
3847 if (!set_installed) { | |
3848 sigAct.sa_flags = SA_SIGINFO|SA_RESTART; | |
3849 } else { | |
3850 sigAct.sa_sigaction = signalHandler; | |
3851 sigAct.sa_flags = SA_SIGINFO|SA_RESTART; | |
3852 } | |
3853 // Save flags, which are set by ours | |
3854 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
3855 sigflags[sig] = sigAct.sa_flags; | |
3856 | |
3857 int ret = sigaction(sig, &sigAct, &oldAct); | |
3858 assert(ret == 0, "check"); | |
3859 | |
3860 void* oldhand2 = oldAct.sa_sigaction | |
3861 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) | |
3862 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); | |
3863 assert(oldhand2 == oldhand, "no concurrent signal handler installation"); | |
3864 } | |
3865 | |
3866 // install signal handlers for signals that HotSpot needs to | |
3867 // handle in order to support Java-level exception handling. | |
3868 | |
3869 void os::Linux::install_signal_handlers() { | |
3870 if (!signal_handlers_are_installed) { | |
3871 signal_handlers_are_installed = true; | |
3872 | |
3873 // signal-chaining | |
3874 typedef void (*signal_setting_t)(); | |
3875 signal_setting_t begin_signal_setting = NULL; | |
3876 signal_setting_t end_signal_setting = NULL; | |
3877 begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t, | |
3878 dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting")); | |
3879 if (begin_signal_setting != NULL) { | |
3880 end_signal_setting = CAST_TO_FN_PTR(signal_setting_t, | |
3881 dlsym(RTLD_DEFAULT, "JVM_end_signal_setting")); | |
3882 get_signal_action = CAST_TO_FN_PTR(get_signal_t, | |
3883 dlsym(RTLD_DEFAULT, "JVM_get_signal_action")); | |
3884 libjsig_is_loaded = true; | |
3885 assert(UseSignalChaining, "should enable signal-chaining"); | |
3886 } | |
3887 if (libjsig_is_loaded) { | |
3888 // Tell libjsig jvm is setting signal handlers | |
3889 (*begin_signal_setting)(); | |
3890 } | |
3891 | |
3892 set_signal_handler(SIGSEGV, true); | |
3893 set_signal_handler(SIGPIPE, true); | |
3894 set_signal_handler(SIGBUS, true); | |
3895 set_signal_handler(SIGILL, true); | |
3896 set_signal_handler(SIGFPE, true); | |
3897 set_signal_handler(SIGXFSZ, true); | |
3898 | |
3899 if (libjsig_is_loaded) { | |
3900 // Tell libjsig jvm finishes setting signal handlers | |
3901 (*end_signal_setting)(); | |
3902 } | |
3903 | |
3904 // 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:
3913
diff
changeset
|
3905 // 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:
3913
diff
changeset
|
3906 // Log that signal checking is off only if -verbose:jni is specified. |
0 | 3907 if (CheckJNICalls) { |
3908 if (libjsig_is_loaded) { | |
3956
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
3909 if (PrintJNIResolving) { |
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
3910 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:
3913
diff
changeset
|
3911 } |
0 | 3912 check_signals = false; |
3913 } | |
3914 if (AllowUserSignalHandlers) { | |
3956
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
3915 if (PrintJNIResolving) { |
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
3916 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:
3913
diff
changeset
|
3917 } |
0 | 3918 check_signals = false; |
3919 } | |
3920 } | |
3921 } | |
3922 } | |
3923 | |
3924 // This is the fastest way to get thread cpu time on Linux. | |
3925 // Returns cpu time (user+sys) for any thread, not only for current. | |
3926 // POSIX compliant clocks are implemented in the kernels 2.6.16+. | |
3927 // It might work on 2.6.10+ with a special kernel/glibc patch. | |
3928 // For reference, please, see IEEE Std 1003.1-2004: | |
3929 // http://www.unix.org/single_unix_specification | |
3930 | |
3931 jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) { | |
3932 struct timespec tp; | |
3933 int rc = os::Linux::clock_gettime(clockid, &tp); | |
3934 assert(rc == 0, "clock_gettime is expected to return 0 code"); | |
3935 | |
4712
e7dead7e90af
7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents:
4082
diff
changeset
|
3936 return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec; |
0 | 3937 } |
3938 | |
3939 ///// | |
3940 // glibc on Linux platform uses non-documented flag | |
3941 // to indicate, that some special sort of signal | |
3942 // trampoline is used. | |
3943 // We will never set this flag, and we should | |
3944 // ignore this flag in our diagnostic | |
3945 #ifdef SIGNIFICANT_SIGNAL_MASK | |
3946 #undef SIGNIFICANT_SIGNAL_MASK | |
3947 #endif | |
3948 #define SIGNIFICANT_SIGNAL_MASK (~0x04000000) | |
3949 | |
3950 static const char* get_signal_handler_name(address handler, | |
3951 char* buf, int buflen) { | |
3952 int offset; | |
3953 bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset); | |
3954 if (found) { | |
3955 // skip directory names | |
3956 const char *p1, *p2; | |
3957 p1 = buf; | |
3958 size_t len = strlen(os::file_separator()); | |
3959 while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len; | |
3960 jio_snprintf(buf, buflen, "%s+0x%x", p1, offset); | |
3961 } else { | |
3962 jio_snprintf(buf, buflen, PTR_FORMAT, handler); | |
3963 } | |
3964 return buf; | |
3965 } | |
3966 | |
3967 static void print_signal_handler(outputStream* st, int sig, | |
3968 char* buf, size_t buflen) { | |
3969 struct sigaction sa; | |
3970 | |
3971 sigaction(sig, NULL, &sa); | |
3972 | |
3973 // See comment for SIGNIFICANT_SIGNAL_MASK define | |
3974 sa.sa_flags &= SIGNIFICANT_SIGNAL_MASK; | |
3975 | |
3976 st->print("%s: ", os::exception_name(sig, buf, buflen)); | |
3977 | |
3978 address handler = (sa.sa_flags & SA_SIGINFO) | |
3979 ? CAST_FROM_FN_PTR(address, sa.sa_sigaction) | |
3980 : CAST_FROM_FN_PTR(address, sa.sa_handler); | |
3981 | |
3982 if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) { | |
3983 st->print("SIG_DFL"); | |
3984 } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) { | |
3985 st->print("SIG_IGN"); | |
3986 } else { | |
3987 st->print("[%s]", get_signal_handler_name(handler, buf, buflen)); | |
3988 } | |
3989 | |
3990 st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask); | |
3991 | |
3992 address rh = VMError::get_resetted_sighandler(sig); | |
3993 // May be, handler was resetted by VMError? | |
3994 if(rh != NULL) { | |
3995 handler = rh; | |
3996 sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK; | |
3997 } | |
3998 | |
3999 st->print(", sa_flags=" PTR32_FORMAT, sa.sa_flags); | |
4000 | |
4001 // Check: is it our handler? | |
4002 if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) || | |
4003 handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler)) { | |
4004 // It is our signal handler | |
4005 // check for flags, reset system-used one! | |
4006 if((int)sa.sa_flags != os::Linux::get_our_sigflags(sig)) { | |
4007 st->print( | |
4008 ", flags was changed from " PTR32_FORMAT ", consider using jsig library", | |
4009 os::Linux::get_our_sigflags(sig)); | |
4010 } | |
4011 } | |
4012 st->cr(); | |
4013 } | |
4014 | |
4015 | |
4016 #define DO_SIGNAL_CHECK(sig) \ | |
4017 if (!sigismember(&check_signal_done, sig)) \ | |
4018 os::Linux::check_signal_handler(sig) | |
4019 | |
4020 // This method is a periodic task to check for misbehaving JNI applications | |
4021 // under CheckJNI, we can add any periodic checks here | |
4022 | |
4023 void os::run_periodic_checks() { | |
4024 | |
4025 if (check_signals == false) return; | |
4026 | |
4027 // SEGV and BUS if overridden could potentially prevent | |
4028 // generation of hs*.log in the event of a crash, debugging | |
4029 // such a case can be very challenging, so we absolutely | |
4030 // check the following for a good measure: | |
4031 DO_SIGNAL_CHECK(SIGSEGV); | |
4032 DO_SIGNAL_CHECK(SIGILL); | |
4033 DO_SIGNAL_CHECK(SIGFPE); | |
4034 DO_SIGNAL_CHECK(SIGBUS); | |
4035 DO_SIGNAL_CHECK(SIGPIPE); | |
4036 DO_SIGNAL_CHECK(SIGXFSZ); | |
4037 | |
4038 | |
4039 // ReduceSignalUsage allows the user to override these handlers | |
4040 // see comments at the very top and jvm_solaris.h | |
4041 if (!ReduceSignalUsage) { | |
4042 DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL); | |
4043 DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL); | |
4044 DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL); | |
4045 DO_SIGNAL_CHECK(BREAK_SIGNAL); | |
4046 } | |
4047 | |
4048 DO_SIGNAL_CHECK(SR_signum); | |
4049 DO_SIGNAL_CHECK(INTERRUPT_SIGNAL); | |
4050 } | |
4051 | |
4052 typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *); | |
4053 | |
4054 static os_sigaction_t os_sigaction = NULL; | |
4055 | |
4056 void os::Linux::check_signal_handler(int sig) { | |
4057 char buf[O_BUFLEN]; | |
4058 address jvmHandler = NULL; | |
4059 | |
4060 | |
4061 struct sigaction act; | |
4062 if (os_sigaction == NULL) { | |
4063 // only trust the default sigaction, in case it has been interposed | |
4064 os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction"); | |
4065 if (os_sigaction == NULL) return; | |
4066 } | |
4067 | |
4068 os_sigaction(sig, (struct sigaction*)NULL, &act); | |
4069 | |
4070 | |
4071 act.sa_flags &= SIGNIFICANT_SIGNAL_MASK; | |
4072 | |
4073 address thisHandler = (act.sa_flags & SA_SIGINFO) | |
4074 ? CAST_FROM_FN_PTR(address, act.sa_sigaction) | |
4075 : CAST_FROM_FN_PTR(address, act.sa_handler) ; | |
4076 | |
4077 | |
4078 switch(sig) { | |
4079 case SIGSEGV: | |
4080 case SIGBUS: | |
4081 case SIGFPE: | |
4082 case SIGPIPE: | |
4083 case SIGILL: | |
4084 case SIGXFSZ: | |
4085 jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler); | |
4086 break; | |
4087 | |
4088 case SHUTDOWN1_SIGNAL: | |
4089 case SHUTDOWN2_SIGNAL: | |
4090 case SHUTDOWN3_SIGNAL: | |
4091 case BREAK_SIGNAL: | |
4092 jvmHandler = (address)user_handler(); | |
4093 break; | |
4094 | |
4095 case INTERRUPT_SIGNAL: | |
4096 jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL); | |
4097 break; | |
4098 | |
4099 default: | |
4100 if (sig == SR_signum) { | |
4101 jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler); | |
4102 } else { | |
4103 return; | |
4104 } | |
4105 break; | |
4106 } | |
4107 | |
4108 if (thisHandler != jvmHandler) { | |
4109 tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN)); | |
4110 tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN)); | |
4111 tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN)); | |
4112 // No need to check this sig any longer | |
4113 sigaddset(&check_signal_done, sig); | |
4114 } else if(os::Linux::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Linux::get_our_sigflags(sig)) { | |
4115 tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN)); | |
4116 tty->print("expected:" PTR32_FORMAT, os::Linux::get_our_sigflags(sig)); | |
4117 tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags); | |
4118 // No need to check this sig any longer | |
4119 sigaddset(&check_signal_done, sig); | |
4120 } | |
4121 | |
4122 // Dump all the signal | |
4123 if (sigismember(&check_signal_done, sig)) { | |
4124 print_signal_handlers(tty, buf, O_BUFLEN); | |
4125 } | |
4126 } | |
4127 | |
4128 extern void report_error(char* file_name, int line_no, char* title, char* format, ...); | |
4129 | |
4130 extern bool signal_name(int signo, char* buf, size_t len); | |
4131 | |
4132 const char* os::exception_name(int exception_code, char* buf, size_t size) { | |
4133 if (0 < exception_code && exception_code <= SIGRTMAX) { | |
4134 // signal | |
4135 if (!signal_name(exception_code, buf, size)) { | |
4136 jio_snprintf(buf, size, "SIG%d", exception_code); | |
4137 } | |
4138 return buf; | |
4139 } else { | |
4140 return NULL; | |
4141 } | |
4142 } | |
4143 | |
4144 // this is called _before_ the most of global arguments have been parsed | |
4145 void os::init(void) { | |
4146 char dummy; /* used to get a guess on initial stack address */ | |
4147 // first_hrtime = gethrtime(); | |
4148 | |
4149 // With LinuxThreads the JavaMain thread pid (primordial thread) | |
4150 // is different than the pid of the java launcher thread. | |
4151 // So, on Linux, the launcher thread pid is passed to the VM | |
4152 // via the sun.java.launcher.pid property. | |
4153 // Use this property instead of getpid() if it was correctly passed. | |
4154 // See bug 6351349. | |
4155 pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid(); | |
4156 | |
4157 _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid(); | |
4158 | |
4159 clock_tics_per_sec = sysconf(_SC_CLK_TCK); | |
4160 | |
4161 init_random(1234567); | |
4162 | |
4163 ThreadCritical::initialize(); | |
4164 | |
4165 Linux::set_page_size(sysconf(_SC_PAGESIZE)); | |
4166 if (Linux::page_size() == -1) { | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1353
diff
changeset
|
4167 fatal(err_msg("os_linux.cpp: os::init: sysconf failed (%s)", |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1353
diff
changeset
|
4168 strerror(errno))); |
0 | 4169 } |
4170 init_page_sizes((size_t) Linux::page_size()); | |
4171 | |
4172 Linux::initialize_system_info(); | |
4173 | |
4174 // main_thread points to the aboriginal thread | |
4175 Linux::_main_thread = pthread_self(); | |
4176 | |
4177 Linux::clock_init(); | |
4178 initial_time_count = os::elapsed_counter(); | |
242 | 4179 pthread_mutex_init(&dl_mutex, NULL); |
0 | 4180 } |
4181 | |
4182 // To install functions for atexit system call | |
4183 extern "C" { | |
4184 static void perfMemory_exit_helper() { | |
4185 perfMemory_exit(); | |
4186 } | |
4187 } | |
4188 | |
4189 // this is called _after_ the global arguments have been parsed | |
4190 jint os::init_2(void) | |
4191 { | |
4192 Linux::fast_thread_clock_init(); | |
4193 | |
4194 // Allocate a single page and mark it as readable for safepoint polling | |
4195 address polling_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | |
4196 guarantee( polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page" ); | |
4197 | |
4198 os::set_polling_page( polling_page ); | |
4199 | |
4200 #ifndef PRODUCT | |
4201 if(Verbose && PrintMiscellaneous) | |
4202 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); | |
4203 #endif | |
4204 | |
4205 if (!UseMembar) { | |
4206 address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | |
4207 guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page"); | |
4208 os::set_memory_serialize_page( mem_serialize_page ); | |
4209 | |
4210 #ifndef PRODUCT | |
4211 if(Verbose && PrintMiscellaneous) | |
4212 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); | |
4213 #endif | |
4214 } | |
4215 | |
3318
188c9a5d6a6d
7040485: Use transparent huge page on linux by default
iveresov
parents:
3292
diff
changeset
|
4216 os::large_page_init(); |
0 | 4217 |
4218 // initialize suspend/resume support - must do this before signal_sets_init() | |
4219 if (SR_initialize() != 0) { | |
4220 perror("SR_initialize failed"); | |
4221 return JNI_ERR; | |
4222 } | |
4223 | |
4224 Linux::signal_sets_init(); | |
4225 Linux::install_signal_handlers(); | |
4226 | |
1867
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4227 // Check minimum allowable stack size for thread creation and to initialize |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4228 // the java system classes, including StackOverflowError - depends on page |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4229 // size. Add a page for compiler2 recursion in main thread. |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4230 // Add in 2*BytesPerWord times page size to account for VM stack during |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4231 // class initialization depending on 32 or 64 bit VM. |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4232 os::Linux::min_stack_allowed = MAX2(os::Linux::min_stack_allowed, |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4233 (size_t)(StackYellowPages+StackRedPages+StackShadowPages+ |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4234 2*BytesPerWord COMPILER2_PRESENT(+1)) * Linux::page_size()); |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4235 |
0 | 4236 size_t threadStackSizeInBytes = ThreadStackSize * K; |
4237 if (threadStackSizeInBytes != 0 && | |
1867
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4238 threadStackSizeInBytes < os::Linux::min_stack_allowed) { |
0 | 4239 tty->print_cr("\nThe stack size specified is too small, " |
4240 "Specify at least %dk", | |
1867
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4241 os::Linux::min_stack_allowed/ K); |
0 | 4242 return JNI_ERR; |
4243 } | |
4244 | |
4245 // Make the stack size a multiple of the page size so that | |
4246 // the yellow/red zones can be guarded. | |
4247 JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, | |
4248 vm_page_size())); | |
4249 | |
4250 Linux::capture_initial_stack(JavaThread::stack_size_at_create()); | |
4251 | |
4252 Linux::libpthread_init(); | |
4253 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
4254 tty->print_cr("[HotSpot is running with %s, %s(%s)]\n", | |
4255 Linux::glibc_version(), Linux::libpthread_version(), | |
4256 Linux::is_floating_stack() ? "floating stack" : "fixed stack"); | |
4257 } | |
4258 | |
141 | 4259 if (UseNUMA) { |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4260 if (!Linux::libnuma_init()) { |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4261 UseNUMA = false; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4262 } else { |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4263 if ((Linux::numa_max_node() < 1)) { |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4264 // There's only one node(they start from 0), disable NUMA. |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4265 UseNUMA = false; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4266 } |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4267 } |
3292
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4268 // With SHM large pages we cannot uncommit a page, so there's not way |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4269 // we can make the adaptive lgrp chunk resizing work. If the user specified |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4270 // both UseNUMA and UseLargePages (or UseSHM) on the command line - warn and |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4271 // disable adaptive resizing. |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4272 if (UseNUMA && UseLargePages && UseSHM) { |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4273 if (!FLAG_IS_DEFAULT(UseNUMA)) { |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4274 if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseSHM)) { |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4275 UseLargePages = false; |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4276 } else { |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4277 warning("UseNUMA is not fully compatible with SHM large pages, disabling adaptive resizing"); |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4278 UseAdaptiveSizePolicy = false; |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4279 UseAdaptiveNUMAChunkSizing = false; |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4280 } |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4281 } else { |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4282 UseNUMA = false; |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4283 } |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4284 } |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4285 if (!UseNUMA && ForceNUMA) { |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4286 UseNUMA = true; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4287 } |
141 | 4288 } |
4289 | |
0 | 4290 if (MaxFDLimit) { |
4291 // set the number of file descriptors to max. print out error | |
4292 // if getrlimit/setrlimit fails but continue regardless. | |
4293 struct rlimit nbr_files; | |
4294 int status = getrlimit(RLIMIT_NOFILE, &nbr_files); | |
4295 if (status != 0) { | |
4296 if (PrintMiscellaneous && (Verbose || WizardMode)) | |
4297 perror("os::init_2 getrlimit failed"); | |
4298 } else { | |
4299 nbr_files.rlim_cur = nbr_files.rlim_max; | |
4300 status = setrlimit(RLIMIT_NOFILE, &nbr_files); | |
4301 if (status != 0) { | |
4302 if (PrintMiscellaneous && (Verbose || WizardMode)) | |
4303 perror("os::init_2 setrlimit failed"); | |
4304 } | |
4305 } | |
4306 } | |
4307 | |
4308 // Initialize lock used to serialize thread creation (see os::create_thread) | |
4309 Linux::set_createThread_lock(new Mutex(Mutex::leaf, "createThread_lock", false)); | |
4310 | |
4311 // at-exit methods are called in the reverse order of their registration. | |
4312 // atexit functions are called on return from main or as a result of a | |
4313 // call to exit(3C). There can be only 32 of these functions registered | |
4314 // and atexit() does not set errno. | |
4315 | |
4316 if (PerfAllowAtExitRegistration) { | |
4317 // only register atexit functions if PerfAllowAtExitRegistration is set. | |
4318 // atexit functions can be delayed until process exit time, which | |
4319 // can be problematic for embedded VM situations. Embedded VMs should | |
4320 // call DestroyJavaVM() to assure that VM resources are released. | |
4321 | |
4322 // note: perfMemory_exit_helper atexit function may be removed in | |
4323 // the future if the appropriate cleanup code can be added to the | |
4324 // VM_Exit VMOperation's doit method. | |
4325 if (atexit(perfMemory_exit_helper) != 0) { | |
4326 warning("os::init2 atexit(perfMemory_exit_helper) failed"); | |
4327 } | |
4328 } | |
4329 | |
4330 // initialize thread priority policy | |
4331 prio_init(); | |
4332 | |
4333 return JNI_OK; | |
4334 } | |
4335 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4336 // this is called at the end of vm_initialization |
3802
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4337 void os::init_3(void) |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4338 { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4339 #ifdef JAVASE_EMBEDDED |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4340 // Start the MemNotifyThread |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4341 if (LowMemoryProtection) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4342 MemNotifyThread::start(); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4343 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4344 return; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4345 #endif |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4346 } |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4347 |
0 | 4348 // Mark the polling page as unreadable |
4349 void os::make_polling_page_unreadable(void) { | |
4350 if( !guard_memory((char*)_polling_page, Linux::page_size()) ) | |
4351 fatal("Could not disable polling page"); | |
4352 }; | |
4353 | |
4354 // Mark the polling page as readable | |
4355 void os::make_polling_page_readable(void) { | |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
4356 if( !linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) { |
0 | 4357 fatal("Could not enable polling page"); |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
4358 } |
0 | 4359 }; |
4360 | |
4361 int os::active_processor_count() { | |
4362 // Linux doesn't yet have a (official) notion of processor sets, | |
4363 // so just return the number of online processors. | |
4364 int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN); | |
4365 assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check"); | |
4366 return online_cpus; | |
4367 } | |
4368 | |
4006 | 4369 void os::set_native_thread_name(const char *name) { |
4370 // Not yet implemented. | |
4371 return; | |
4372 } | |
4373 | |
0 | 4374 bool os::distribute_processes(uint length, uint* distribution) { |
4375 // Not yet implemented. | |
4376 return false; | |
4377 } | |
4378 | |
4379 bool os::bind_to_processor(uint processor_id) { | |
4380 // Not yet implemented. | |
4381 return false; | |
4382 } | |
4383 | |
4384 /// | |
4385 | |
4386 // Suspends the target using the signal mechanism and then grabs the PC before | |
4387 // resuming the target. Used by the flat-profiler only | |
4388 ExtendedPC os::get_thread_pc(Thread* thread) { | |
4389 // Make sure that it is called by the watcher for the VMThread | |
4390 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); | |
4391 assert(thread->is_VM_thread(), "Can only be called for VMThread"); | |
4392 | |
4393 ExtendedPC epc; | |
4394 | |
4395 OSThread* osthread = thread->osthread(); | |
4396 if (do_suspend(osthread)) { | |
4397 if (osthread->ucontext() != NULL) { | |
4398 epc = os::Linux::ucontext_get_pc(osthread->ucontext()); | |
4399 } else { | |
4400 // NULL context is unexpected, double-check this is the VMThread | |
4401 guarantee(thread->is_VM_thread(), "can only be called for VMThread"); | |
4402 } | |
4403 do_resume(osthread); | |
4404 } | |
4405 // failure means pthread_kill failed for some reason - arguably this is | |
4406 // a fatal problem, but such problems are ignored elsewhere | |
4407 | |
4408 return epc; | |
4409 } | |
4410 | |
4411 int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) | |
4412 { | |
4413 if (is_NPTL()) { | |
4414 return pthread_cond_timedwait(_cond, _mutex, _abstime); | |
4415 } else { | |
4416 #ifndef IA64 | |
4417 // 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control | |
4418 // word back to default 64bit precision if condvar is signaled. Java | |
4419 // wants 53bit precision. Save and restore current value. | |
4420 int fpu = get_fpu_control_word(); | |
4421 #endif // IA64 | |
4422 int status = pthread_cond_timedwait(_cond, _mutex, _abstime); | |
4423 #ifndef IA64 | |
4424 set_fpu_control_word(fpu); | |
4425 #endif // IA64 | |
4426 return status; | |
4427 } | |
4428 } | |
4429 | |
4430 //////////////////////////////////////////////////////////////////////////////// | |
4431 // debug support | |
4432 | |
4433 static address same_page(address x, address y) { | |
4434 int page_bits = -os::vm_page_size(); | |
4435 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) | |
4436 return x; | |
4437 else if (x > y) | |
4438 return (address)(intptr_t(y) | ~page_bits) + 1; | |
4439 else | |
4440 return (address)(intptr_t(y) & page_bits); | |
4441 } | |
4442 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4443 bool os::find(address addr, outputStream* st) { |
0 | 4444 Dl_info dlinfo; |
4445 memset(&dlinfo, 0, sizeof(dlinfo)); | |
4446 if (dladdr(addr, &dlinfo)) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4447 st->print(PTR_FORMAT ": ", addr); |
0 | 4448 if (dlinfo.dli_sname != NULL) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4449 st->print("%s+%#x", dlinfo.dli_sname, |
0 | 4450 addr - (intptr_t)dlinfo.dli_saddr); |
4451 } else if (dlinfo.dli_fname) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4452 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); |
0 | 4453 } else { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4454 st->print("<absolute address>"); |
0 | 4455 } |
4456 if (dlinfo.dli_fname) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4457 st->print(" in %s", dlinfo.dli_fname); |
0 | 4458 } |
4459 if (dlinfo.dli_fbase) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4460 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); |
0 | 4461 } |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4462 st->cr(); |
0 | 4463 |
4464 if (Verbose) { | |
4465 // decode some bytes around the PC | |
4466 address begin = same_page(addr-40, addr); | |
4467 address end = same_page(addr+40, addr); | |
4468 address lowest = (address) dlinfo.dli_sname; | |
4469 if (!lowest) lowest = (address) dlinfo.dli_fbase; | |
4470 if (begin < lowest) begin = lowest; | |
4471 Dl_info dlinfo2; | |
4472 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr | |
4473 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) | |
4474 end = (address) dlinfo2.dli_saddr; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4475 Disassembler::decode(begin, end, st); |
0 | 4476 } |
4477 return true; | |
4478 } | |
4479 return false; | |
4480 } | |
4481 | |
4482 //////////////////////////////////////////////////////////////////////////////// | |
4483 // misc | |
4484 | |
4485 // This does not do anything on Linux. This is basically a hook for being | |
4486 // able to use structured exception handling (thread-local exception filters) | |
4487 // on, e.g., Win32. | |
4488 void | |
4993
897b7d18bebc
added RiCompiledMethod.execute and the required VM infrastructure
Lukas Stadler <lukas.stadler@jku.at>
parents:
4970
diff
changeset
|
4489 os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, nmethod* nm, |
0 | 4490 JavaCallArguments* args, Thread* thread) { |
4993
897b7d18bebc
added RiCompiledMethod.execute and the required VM infrastructure
Lukas Stadler <lukas.stadler@jku.at>
parents:
4970
diff
changeset
|
4491 f(value, method, nm, args, thread); |
0 | 4492 } |
4493 | |
4494 void os::print_statistics() { | |
4495 } | |
4496 | |
4497 int os::message_box(const char* title, const char* message) { | |
4498 int i; | |
4499 fdStream err(defaultStream::error_fd()); | |
4500 for (i = 0; i < 78; i++) err.print_raw("="); | |
4501 err.cr(); | |
4502 err.print_raw_cr(title); | |
4503 for (i = 0; i < 78; i++) err.print_raw("-"); | |
4504 err.cr(); | |
4505 err.print_raw_cr(message); | |
4506 for (i = 0; i < 78; i++) err.print_raw("="); | |
4507 err.cr(); | |
4508 | |
4509 char buf[16]; | |
4510 // Prevent process from exiting upon "read error" without consuming all CPU | |
4511 while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); } | |
4512 | |
4513 return buf[0] == 'y' || buf[0] == 'Y'; | |
4514 } | |
4515 | |
4516 int os::stat(const char *path, struct stat *sbuf) { | |
4517 char pathbuf[MAX_PATH]; | |
4518 if (strlen(path) > MAX_PATH - 1) { | |
4519 errno = ENAMETOOLONG; | |
4520 return -1; | |
4521 } | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4522 os::native_path(strcpy(pathbuf, path)); |
0 | 4523 return ::stat(pathbuf, sbuf); |
4524 } | |
4525 | |
4526 bool os::check_heap(bool force) { | |
4527 return true; | |
4528 } | |
4529 | |
4530 int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) { | |
4531 return ::vsnprintf(buf, count, format, args); | |
4532 } | |
4533 | |
4534 // Is a (classpath) directory empty? | |
4535 bool os::dir_is_empty(const char* path) { | |
4536 DIR *dir = NULL; | |
4537 struct dirent *ptr; | |
4538 | |
4539 dir = opendir(path); | |
4540 if (dir == NULL) return true; | |
4541 | |
4542 /* Scan the directory */ | |
4543 bool result = true; | |
4544 char buf[sizeof(struct dirent) + MAX_PATH]; | |
4545 while (result && (ptr = ::readdir(dir)) != NULL) { | |
4546 if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) { | |
4547 result = false; | |
4548 } | |
4549 } | |
4550 closedir(dir); | |
4551 return result; | |
4552 } | |
4553 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4554 // 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
|
4555 // from src/solaris/hpi/src/system_md.c |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4556 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4557 #ifndef O_DELETE |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4558 #define O_DELETE 0x10000 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4559 #endif |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4560 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4561 // 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
|
4562 // 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
|
4563 // 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
|
4564 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4565 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
|
4566 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4567 if (strlen(path) > MAX_PATH - 1) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4568 errno = ENAMETOOLONG; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4569 return -1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4570 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4571 int fd; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4572 int o_delete = (oflag & O_DELETE); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4573 oflag = oflag & ~O_DELETE; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4574 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4575 fd = ::open64(path, oflag, mode); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4576 if (fd == -1) return -1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4577 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4578 //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
|
4579 { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4580 struct stat64 buf64; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4581 int ret = ::fstat64(fd, &buf64); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4582 int st_mode = buf64.st_mode; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4583 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4584 if (ret != -1) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4585 if ((st_mode & S_IFMT) == S_IFDIR) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4586 errno = EISDIR; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4587 ::close(fd); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4588 return -1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4589 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4590 } else { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4591 ::close(fd); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4592 return -1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4593 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4594 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4595 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4596 /* |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4597 * 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
|
4598 * specifically destined for a subprocess should have the |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4599 * 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
|
4600 * 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
|
4601 * 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
|
4602 * UNIXProcess.c), and this in turn might: |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4603 * |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4604 * - 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
|
4605 * descriptors, resulting in mysterious hangs, or |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4606 * |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4607 * - 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
|
4608 * suffering from bug 1085341. |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4609 * |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4610 * (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
|
4611 * design flaw) |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4612 * |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4613 * See: |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4614 * 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
|
4615 * 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
|
4616 * 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
|
4617 */ |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4618 #ifdef FD_CLOEXEC |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4619 { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4620 int flags = ::fcntl(fd, F_GETFD); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4621 if (flags != -1) |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4622 ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4623 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4624 #endif |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4625 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4626 if (o_delete != 0) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4627 ::unlink(path); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4628 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4629 return fd; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4630 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4631 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4632 |
0 | 4633 // create binary file, rewriting existing file if required |
4634 int os::create_binary_file(const char* path, bool rewrite_existing) { | |
4635 int oflags = O_WRONLY | O_CREAT; | |
4636 if (!rewrite_existing) { | |
4637 oflags |= O_EXCL; | |
4638 } | |
4639 return ::open64(path, oflags, S_IREAD | S_IWRITE); | |
4640 } | |
4641 | |
4642 // return current position of file pointer | |
4643 jlong os::current_file_offset(int fd) { | |
4644 return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR); | |
4645 } | |
4646 | |
4647 // move file pointer to the specified offset | |
4648 jlong os::seek_to_file_offset(int fd, jlong offset) { | |
4649 return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET); | |
4650 } | |
4651 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4652 // This code originates from JDK's sysAvailable |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4653 // from src/solaris/hpi/src/native_threads/src/sys_api_td.c |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4654 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4655 int os::available(int fd, jlong *bytes) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4656 jlong cur, end; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4657 int mode; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4658 struct stat64 buf64; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4659 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4660 if (::fstat64(fd, &buf64) >= 0) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4661 mode = buf64.st_mode; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4662 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
|
4663 /* |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4664 * 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
|
4665 * 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
|
4666 * blocking, interruptible calls in this file. |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4667 */ |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4668 int n; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4669 if (::ioctl(fd, FIONREAD, &n) >= 0) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4670 *bytes = n; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4671 return 1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4672 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4673 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4674 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4675 if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4676 return 0; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4677 } 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
|
4678 return 0; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4679 } else if (::lseek64(fd, cur, SEEK_SET) == -1) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4680 return 0; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4681 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4682 *bytes = end - cur; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4683 return 1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4684 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4685 |
2033
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
4686 int os::socket_available(int fd, jint *pbytes) { |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
4687 // Linux doc says EINTR not returned, unlike Solaris |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
4688 int ret = ::ioctl(fd, FIONREAD, pbytes); |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
4689 |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
4690 //%% note ioctl can return 0 when successful, JVM_SocketAvailable |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
4691 // is expected to return 0 on failure and 1 on success to the jdk. |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
4692 return (ret < 0) ? 0 : 1; |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
4693 } |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
4694 |
0 | 4695 // Map a block of memory. |
4696 char* os::map_memory(int fd, const char* file_name, size_t file_offset, | |
4697 char *addr, size_t bytes, bool read_only, | |
4698 bool allow_exec) { | |
4699 int prot; | |
4700 int flags; | |
4701 | |
4702 if (read_only) { | |
4703 prot = PROT_READ; | |
4704 flags = MAP_SHARED; | |
4705 } else { | |
4706 prot = PROT_READ | PROT_WRITE; | |
4707 flags = MAP_PRIVATE; | |
4708 } | |
4709 | |
4710 if (allow_exec) { | |
4711 prot |= PROT_EXEC; | |
4712 } | |
4713 | |
4714 if (addr != NULL) { | |
4715 flags |= MAP_FIXED; | |
4716 } | |
4717 | |
4718 char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags, | |
4719 fd, file_offset); | |
4720 if (mapped_address == MAP_FAILED) { | |
4721 return NULL; | |
4722 } | |
4723 return mapped_address; | |
4724 } | |
4725 | |
4726 | |
4727 // Remap a block of memory. | |
4728 char* os::remap_memory(int fd, const char* file_name, size_t file_offset, | |
4729 char *addr, size_t bytes, bool read_only, | |
4730 bool allow_exec) { | |
4731 // same as map_memory() on this OS | |
4732 return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only, | |
4733 allow_exec); | |
4734 } | |
4735 | |
4736 | |
4737 // Unmap a block of memory. | |
4738 bool os::unmap_memory(char* addr, size_t bytes) { | |
4739 return munmap(addr, bytes) == 0; | |
4740 } | |
4741 | |
4742 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time); | |
4743 | |
4744 static clockid_t thread_cpu_clockid(Thread* thread) { | |
4745 pthread_t tid = thread->osthread()->pthread_id(); | |
4746 clockid_t clockid; | |
4747 | |
4748 // Get thread clockid | |
4749 int rc = os::Linux::pthread_getcpuclockid(tid, &clockid); | |
4750 assert(rc == 0, "pthread_getcpuclockid is expected to return 0 code"); | |
4751 return clockid; | |
4752 } | |
4753 | |
4754 // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool) | |
4755 // are used by JVM M&M and JVMTI to get user+sys or user CPU time | |
4756 // of a thread. | |
4757 // | |
4758 // current_thread_cpu_time() and thread_cpu_time(Thread*) returns | |
4759 // the fast estimate available on the platform. | |
4760 | |
4761 jlong os::current_thread_cpu_time() { | |
4762 if (os::Linux::supports_fast_thread_cpu_time()) { | |
4763 return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID); | |
4764 } else { | |
4765 // return user + sys since the cost is the same | |
4766 return slow_thread_cpu_time(Thread::current(), true /* user + sys */); | |
4767 } | |
4768 } | |
4769 | |
4770 jlong os::thread_cpu_time(Thread* thread) { | |
4771 // consistent with what current_thread_cpu_time() returns | |
4772 if (os::Linux::supports_fast_thread_cpu_time()) { | |
4773 return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread)); | |
4774 } else { | |
4775 return slow_thread_cpu_time(thread, true /* user + sys */); | |
4776 } | |
4777 } | |
4778 | |
4779 jlong os::current_thread_cpu_time(bool user_sys_cpu_time) { | |
4780 if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) { | |
4781 return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID); | |
4782 } else { | |
4783 return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time); | |
4784 } | |
4785 } | |
4786 | |
4787 jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) { | |
4788 if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) { | |
4789 return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread)); | |
4790 } else { | |
4791 return slow_thread_cpu_time(thread, user_sys_cpu_time); | |
4792 } | |
4793 } | |
4794 | |
4795 // | |
4796 // -1 on error. | |
4797 // | |
4798 | |
4799 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) { | |
4800 static bool proc_pid_cpu_avail = true; | |
4801 static bool proc_task_unchecked = true; | |
4802 static const char *proc_stat_path = "/proc/%d/stat"; | |
4803 pid_t tid = thread->osthread()->thread_id(); | |
4804 int i; | |
4805 char *s; | |
4806 char stat[2048]; | |
4807 int statlen; | |
4808 char proc_name[64]; | |
4809 int count; | |
4810 long sys_time, user_time; | |
4811 char string[64]; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4812 char cdummy; |
0 | 4813 int idummy; |
4814 long ldummy; | |
4815 FILE *fp; | |
4816 | |
4817 // We first try accessing /proc/<pid>/cpu since this is faster to | |
4818 // process. If this file is not present (linux kernels 2.5 and above) | |
4819 // then we open /proc/<pid>/stat. | |
4820 if ( proc_pid_cpu_avail ) { | |
4821 sprintf(proc_name, "/proc/%d/cpu", tid); | |
4822 fp = fopen(proc_name, "r"); | |
4823 if ( fp != NULL ) { | |
4824 count = fscanf( fp, "%s %lu %lu\n", string, &user_time, &sys_time); | |
4825 fclose(fp); | |
4826 if ( count != 3 ) return -1; | |
4827 | |
4828 if (user_sys_cpu_time) { | |
4829 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec); | |
4830 } else { | |
4831 return (jlong)user_time * (1000000000 / clock_tics_per_sec); | |
4832 } | |
4833 } | |
4834 else proc_pid_cpu_avail = false; | |
4835 } | |
4836 | |
4837 // The /proc/<tid>/stat aggregates per-process usage on | |
4838 // new Linux kernels 2.6+ where NPTL is supported. | |
4839 // The /proc/self/task/<tid>/stat still has the per-thread usage. | |
4840 // See bug 6328462. | |
4841 // There can be no directory /proc/self/task on kernels 2.4 with NPTL | |
4842 // and possibly in some other cases, so we check its availability. | |
4843 if (proc_task_unchecked && os::Linux::is_NPTL()) { | |
4844 // This is executed only once | |
4845 proc_task_unchecked = false; | |
4846 fp = fopen("/proc/self/task", "r"); | |
4847 if (fp != NULL) { | |
4848 proc_stat_path = "/proc/self/task/%d/stat"; | |
4849 fclose(fp); | |
4850 } | |
4851 } | |
4852 | |
4853 sprintf(proc_name, proc_stat_path, tid); | |
4854 fp = fopen(proc_name, "r"); | |
4855 if ( fp == NULL ) return -1; | |
4856 statlen = fread(stat, 1, 2047, fp); | |
4857 stat[statlen] = '\0'; | |
4858 fclose(fp); | |
4859 | |
4860 // Skip pid and the command string. Note that we could be dealing with | |
4861 // weird command names, e.g. user could decide to rename java launcher | |
4862 // to "java 1.4.2 :)", then the stat file would look like | |
4863 // 1234 (java 1.4.2 :)) R ... ... | |
4864 // We don't really need to know the command string, just find the last | |
4865 // occurrence of ")" and then start parsing from there. See bug 4726580. | |
4866 s = strrchr(stat, ')'); | |
4867 i = 0; | |
4868 if (s == NULL ) return -1; | |
4869 | |
4870 // Skip blank chars | |
4871 do s++; while (isspace(*s)); | |
4872 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4873 count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu", |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4874 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy, |
0 | 4875 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy, |
4876 &user_time, &sys_time); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4877 if ( count != 13 ) return -1; |
0 | 4878 if (user_sys_cpu_time) { |
4879 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec); | |
4880 } else { | |
4881 return (jlong)user_time * (1000000000 / clock_tics_per_sec); | |
4882 } | |
4883 } | |
4884 | |
4885 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { | |
4886 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits | |
4887 info_ptr->may_skip_backward = false; // elapsed time not wall time | |
4888 info_ptr->may_skip_forward = false; // elapsed time not wall time | |
4889 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned | |
4890 } | |
4891 | |
4892 void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { | |
4893 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits | |
4894 info_ptr->may_skip_backward = false; // elapsed time not wall time | |
4895 info_ptr->may_skip_forward = false; // elapsed time not wall time | |
4896 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned | |
4897 } | |
4898 | |
4899 bool os::is_thread_cpu_time_supported() { | |
4900 return true; | |
4901 } | |
4902 | |
4903 // System loadavg support. Returns -1 if load average cannot be obtained. | |
4904 // Linux doesn't yet have a (official) notion of processor sets, | |
4905 // so just return the system wide load average. | |
4906 int os::loadavg(double loadavg[], int nelem) { | |
4907 return ::getloadavg(loadavg, nelem); | |
4908 } | |
4909 | |
4910 void os::pause() { | |
4911 char filename[MAX_PATH]; | |
4912 if (PauseAtStartupFile && PauseAtStartupFile[0]) { | |
4913 jio_snprintf(filename, MAX_PATH, PauseAtStartupFile); | |
4914 } else { | |
4915 jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id()); | |
4916 } | |
4917 | |
4918 int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); | |
4919 if (fd != -1) { | |
4920 struct stat buf; | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
4921 ::close(fd); |
0 | 4922 while (::stat(filename, &buf) == 0) { |
4923 (void)::poll(NULL, 0, 100); | |
4924 } | |
4925 } else { | |
4926 jio_fprintf(stderr, | |
4927 "Could not open pause file '%s', continuing immediately.\n", filename); | |
4928 } | |
4929 } | |
4930 | |
4931 | |
4932 // Refer to the comments in os_solaris.cpp park-unpark. | |
4933 // | |
4934 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can | |
4935 // hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable. | |
4936 // For specifics regarding the bug see GLIBC BUGID 261237 : | |
4937 // http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html. | |
4938 // Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future | |
4939 // will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar | |
4940 // is used. (The simple C test-case provided in the GLIBC bug report manifests the | |
4941 // hang). The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos() | |
4942 // and monitorenter when we're using 1-0 locking. All those operations may result in | |
4943 // calls to pthread_cond_timedwait(). Using LD_ASSUME_KERNEL to use an older version | |
4944 // of libpthread avoids the problem, but isn't practical. | |
4945 // | |
4946 // Possible remedies: | |
4947 // | |
4948 // 1. Establish a minimum relative wait time. 50 to 100 msecs seems to work. | |
4949 // This is palliative and probabilistic, however. If the thread is preempted | |
4950 // between the call to compute_abstime() and pthread_cond_timedwait(), more | |
4951 // than the minimum period may have passed, and the abstime may be stale (in the | |
4952 // past) resultin in a hang. Using this technique reduces the odds of a hang | |
4953 // but the JVM is still vulnerable, particularly on heavily loaded systems. | |
4954 // | |
4955 // 2. Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead | |
4956 // of the usual flag-condvar-mutex idiom. The write side of the pipe is set | |
4957 // NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo) | |
4958 // reduces to poll()+read(). This works well, but consumes 2 FDs per extant | |
4959 // thread. | |
4960 // | |
4961 // 3. Embargo pthread_cond_timedwait() and implement a native "chron" thread | |
4962 // that manages timeouts. We'd emulate pthread_cond_timedwait() by enqueuing | |
4963 // a timeout request to the chron thread and then blocking via pthread_cond_wait(). | |
4964 // This also works well. In fact it avoids kernel-level scalability impediments | |
4965 // on certain platforms that don't handle lots of active pthread_cond_timedwait() | |
4966 // timers in a graceful fashion. | |
4967 // | |
4968 // 4. When the abstime value is in the past it appears that control returns | |
4969 // correctly from pthread_cond_timedwait(), but the condvar is left corrupt. | |
4970 // Subsequent timedwait/wait calls may hang indefinitely. Given that, we | |
4971 // can avoid the problem by reinitializing the condvar -- by cond_destroy() | |
4972 // followed by cond_init() -- after all calls to pthread_cond_timedwait(). | |
4973 // It may be possible to avoid reinitialization by checking the return | |
4974 // value from pthread_cond_timedwait(). In addition to reinitializing the | |
4975 // condvar we must establish the invariant that cond_signal() is only called | |
4976 // within critical sections protected by the adjunct mutex. This prevents | |
4977 // cond_signal() from "seeing" a condvar that's in the midst of being | |
4978 // reinitialized or that is corrupt. Sadly, this invariant obviates the | |
4979 // desirable signal-after-unlock optimization that avoids futile context switching. | |
4980 // | |
4981 // I'm also concerned that some versions of NTPL might allocate an auxilliary | |
4982 // structure when a condvar is used or initialized. cond_destroy() would | |
4983 // release the helper structure. Our reinitialize-after-timedwait fix | |
4984 // put excessive stress on malloc/free and locks protecting the c-heap. | |
4985 // | |
4986 // We currently use (4). See the WorkAroundNTPLTimedWaitHang flag. | |
4987 // It may be possible to refine (4) by checking the kernel and NTPL verisons | |
4988 // and only enabling the work-around for vulnerable environments. | |
4989 | |
4990 // utility to compute the abstime argument to timedwait: | |
4991 // millis is the relative timeout time | |
4992 // abstime will be the absolute timeout time | |
4993 // TODO: replace compute_abstime() with unpackTime() | |
4994 | |
4995 static struct timespec* compute_abstime(timespec* abstime, jlong millis) { | |
4996 if (millis < 0) millis = 0; | |
4997 struct timeval now; | |
4998 int status = gettimeofday(&now, NULL); | |
4999 assert(status == 0, "gettimeofday"); | |
5000 jlong seconds = millis / 1000; | |
5001 millis %= 1000; | |
5002 if (seconds > 50000000) { // see man cond_timedwait(3T) | |
5003 seconds = 50000000; | |
5004 } | |
5005 abstime->tv_sec = now.tv_sec + seconds; | |
5006 long usec = now.tv_usec + millis * 1000; | |
5007 if (usec >= 1000000) { | |
5008 abstime->tv_sec += 1; | |
5009 usec -= 1000000; | |
5010 } | |
5011 abstime->tv_nsec = usec * 1000; | |
5012 return abstime; | |
5013 } | |
5014 | |
5015 | |
5016 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. | |
5017 // Conceptually TryPark() should be equivalent to park(0). | |
5018 | |
5019 int os::PlatformEvent::TryPark() { | |
5020 for (;;) { | |
5021 const int v = _Event ; | |
5022 guarantee ((v == 0) || (v == 1), "invariant") ; | |
5023 if (Atomic::cmpxchg (0, &_Event, v) == v) return v ; | |
5024 } | |
5025 } | |
5026 | |
5027 void os::PlatformEvent::park() { // AKA "down()" | |
5028 // Invariant: Only the thread associated with the Event/PlatformEvent | |
5029 // may call park(). | |
5030 // TODO: assert that _Assoc != NULL or _Assoc == Self | |
5031 int v ; | |
5032 for (;;) { | |
5033 v = _Event ; | |
5034 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ; | |
5035 } | |
5036 guarantee (v >= 0, "invariant") ; | |
5037 if (v == 0) { | |
5038 // Do this the hard way by blocking ... | |
5039 int status = pthread_mutex_lock(_mutex); | |
5040 assert_status(status == 0, status, "mutex_lock"); | |
5041 guarantee (_nParked == 0, "invariant") ; | |
5042 ++ _nParked ; | |
5043 while (_Event < 0) { | |
5044 status = pthread_cond_wait(_cond, _mutex); | |
5045 // for some reason, under 2.7 lwp_cond_wait() may return ETIME ... | |
5046 // Treat this the same as if the wait was interrupted | |
5047 if (status == ETIME) { status = EINTR; } | |
5048 assert_status(status == 0 || status == EINTR, status, "cond_wait"); | |
5049 } | |
5050 -- _nParked ; | |
5051 | |
5052 // In theory we could move the ST of 0 into _Event past the unlock(), | |
5053 // but then we'd need a MEMBAR after the ST. | |
5054 _Event = 0 ; | |
5055 status = pthread_mutex_unlock(_mutex); | |
5056 assert_status(status == 0, status, "mutex_unlock"); | |
5057 } | |
5058 guarantee (_Event >= 0, "invariant") ; | |
5059 } | |
5060 | |
5061 int os::PlatformEvent::park(jlong millis) { | |
5062 guarantee (_nParked == 0, "invariant") ; | |
5063 | |
5064 int v ; | |
5065 for (;;) { | |
5066 v = _Event ; | |
5067 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ; | |
5068 } | |
5069 guarantee (v >= 0, "invariant") ; | |
5070 if (v != 0) return OS_OK ; | |
5071 | |
5072 // We do this the hard way, by blocking the thread. | |
5073 // Consider enforcing a minimum timeout value. | |
5074 struct timespec abst; | |
5075 compute_abstime(&abst, millis); | |
5076 | |
5077 int ret = OS_TIMEOUT; | |
5078 int status = pthread_mutex_lock(_mutex); | |
5079 assert_status(status == 0, status, "mutex_lock"); | |
5080 guarantee (_nParked == 0, "invariant") ; | |
5081 ++_nParked ; | |
5082 | |
5083 // Object.wait(timo) will return because of | |
5084 // (a) notification | |
5085 // (b) timeout | |
5086 // (c) thread.interrupt | |
5087 // | |
5088 // Thread.interrupt and object.notify{All} both call Event::set. | |
5089 // That is, we treat thread.interrupt as a special case of notification. | |
5090 // The underlying Solaris implementation, cond_timedwait, admits | |
5091 // spurious/premature wakeups, but the JLS/JVM spec prevents the | |
5092 // JVM from making those visible to Java code. As such, we must | |
5093 // filter out spurious wakeups. We assume all ETIME returns are valid. | |
5094 // | |
5095 // TODO: properly differentiate simultaneous notify+interrupt. | |
5096 // In that case, we should propagate the notify to another waiter. | |
5097 | |
5098 while (_Event < 0) { | |
5099 status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst); | |
5100 if (status != 0 && WorkAroundNPTLTimedWaitHang) { | |
5101 pthread_cond_destroy (_cond); | |
5102 pthread_cond_init (_cond, NULL) ; | |
5103 } | |
5104 assert_status(status == 0 || status == EINTR || | |
5105 status == ETIME || status == ETIMEDOUT, | |
5106 status, "cond_timedwait"); | |
5107 if (!FilterSpuriousWakeups) break ; // previous semantics | |
5108 if (status == ETIME || status == ETIMEDOUT) break ; | |
5109 // We consume and ignore EINTR and spurious wakeups. | |
5110 } | |
5111 --_nParked ; | |
5112 if (_Event >= 0) { | |
5113 ret = OS_OK; | |
5114 } | |
5115 _Event = 0 ; | |
5116 status = pthread_mutex_unlock(_mutex); | |
5117 assert_status(status == 0, status, "mutex_unlock"); | |
5118 assert (_nParked == 0, "invariant") ; | |
5119 return ret; | |
5120 } | |
5121 | |
5122 void os::PlatformEvent::unpark() { | |
5123 int v, AnyWaiters ; | |
5124 for (;;) { | |
5125 v = _Event ; | |
5126 if (v > 0) { | |
5127 // The LD of _Event could have reordered or be satisfied | |
5128 // by a read-aside from this processor's write buffer. | |
5129 // To avoid problems execute a barrier and then | |
5130 // ratify the value. | |
5131 OrderAccess::fence() ; | |
5132 if (_Event == v) return ; | |
5133 continue ; | |
5134 } | |
5135 if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ; | |
5136 } | |
5137 if (v < 0) { | |
5138 // Wait for the thread associated with the event to vacate | |
5139 int status = pthread_mutex_lock(_mutex); | |
5140 assert_status(status == 0, status, "mutex_lock"); | |
5141 AnyWaiters = _nParked ; | |
5142 assert (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ; | |
5143 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { | |
5144 AnyWaiters = 0 ; | |
5145 pthread_cond_signal (_cond); | |
5146 } | |
5147 status = pthread_mutex_unlock(_mutex); | |
5148 assert_status(status == 0, status, "mutex_unlock"); | |
5149 if (AnyWaiters != 0) { | |
5150 status = pthread_cond_signal(_cond); | |
5151 assert_status(status == 0, status, "cond_signal"); | |
5152 } | |
5153 } | |
5154 | |
5155 // Note that we signal() _after dropping the lock for "immortal" Events. | |
5156 // This is safe and avoids a common class of futile wakeups. In rare | |
5157 // circumstances this can cause a thread to return prematurely from | |
5158 // cond_{timed}wait() but the spurious wakeup is benign and the victim will | |
5159 // simply re-test the condition and re-park itself. | |
5160 } | |
5161 | |
5162 | |
5163 // JSR166 | |
5164 // ------------------------------------------------------- | |
5165 | |
5166 /* | |
5167 * The solaris and linux implementations of park/unpark are fairly | |
5168 * conservative for now, but can be improved. They currently use a | |
5169 * mutex/condvar pair, plus a a count. | |
5170 * Park decrements count if > 0, else does a condvar wait. Unpark | |
5171 * sets count to 1 and signals condvar. Only one thread ever waits | |
5172 * on the condvar. Contention seen when trying to park implies that someone | |
5173 * is unparking you, so don't wait. And spurious returns are fine, so there | |
5174 * is no need to track notifications. | |
5175 */ | |
5176 | |
5177 #define MAX_SECS 100000000 | |
5178 /* | |
5179 * This code is common to linux and solaris and will be moved to a | |
5180 * common place in dolphin. | |
5181 * | |
5182 * The passed in time value is either a relative time in nanoseconds | |
5183 * or an absolute time in milliseconds. Either way it has to be unpacked | |
5184 * into suitable seconds and nanoseconds components and stored in the | |
5185 * given timespec structure. | |
5186 * Given time is a 64-bit value and the time_t used in the timespec is only | |
5187 * a signed-32-bit value (except on 64-bit Linux) we have to watch for | |
5188 * overflow if times way in the future are given. Further on Solaris versions | |
5189 * prior to 10 there is a restriction (see cond_timedwait) that the specified | |
5190 * number of seconds, in abstime, is less than current_time + 100,000,000. | |
5191 * As it will be 28 years before "now + 100000000" will overflow we can | |
5192 * ignore overflow and just impose a hard-limit on seconds using the value | |
5193 * of "now + 100,000,000". This places a limit on the timeout of about 3.17 | |
5194 * years from "now". | |
5195 */ | |
5196 | |
5197 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { | |
5198 assert (time > 0, "convertTime"); | |
5199 | |
5200 struct timeval now; | |
5201 int status = gettimeofday(&now, NULL); | |
5202 assert(status == 0, "gettimeofday"); | |
5203 | |
5204 time_t max_secs = now.tv_sec + MAX_SECS; | |
5205 | |
5206 if (isAbsolute) { | |
5207 jlong secs = time / 1000; | |
5208 if (secs > max_secs) { | |
5209 absTime->tv_sec = max_secs; | |
5210 } | |
5211 else { | |
5212 absTime->tv_sec = secs; | |
5213 } | |
5214 absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; | |
5215 } | |
5216 else { | |
5217 jlong secs = time / NANOSECS_PER_SEC; | |
5218 if (secs >= MAX_SECS) { | |
5219 absTime->tv_sec = max_secs; | |
5220 absTime->tv_nsec = 0; | |
5221 } | |
5222 else { | |
5223 absTime->tv_sec = now.tv_sec + secs; | |
5224 absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; | |
5225 if (absTime->tv_nsec >= NANOSECS_PER_SEC) { | |
5226 absTime->tv_nsec -= NANOSECS_PER_SEC; | |
5227 ++absTime->tv_sec; // note: this must be <= max_secs | |
5228 } | |
5229 } | |
5230 } | |
5231 assert(absTime->tv_sec >= 0, "tv_sec < 0"); | |
5232 assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs"); | |
5233 assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); | |
5234 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); | |
5235 } | |
5236 | |
5237 void Parker::park(bool isAbsolute, jlong time) { | |
5238 // Optional fast-path check: | |
5239 // Return immediately if a permit is available. | |
5240 if (_counter > 0) { | |
5241 _counter = 0 ; | |
1117
95e9083cf4a7
6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents:
1010
diff
changeset
|
5242 OrderAccess::fence(); |
0 | 5243 return ; |
5244 } | |
5245 | |
5246 Thread* thread = Thread::current(); | |
5247 assert(thread->is_Java_thread(), "Must be JavaThread"); | |
5248 JavaThread *jt = (JavaThread *)thread; | |
5249 | |
5250 // Optional optimization -- avoid state transitions if there's an interrupt pending. | |
5251 // Check interrupt before trying to wait | |
5252 if (Thread::is_interrupted(thread, false)) { | |
5253 return; | |
5254 } | |
5255 | |
5256 // Next, demultiplex/decode time arguments | |
5257 timespec absTime; | |
1865
1c352af0135d
6763959: java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
acorn
parents:
1750
diff
changeset
|
5258 if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all |
0 | 5259 return; |
5260 } | |
5261 if (time > 0) { | |
5262 unpackTime(&absTime, isAbsolute, time); | |
5263 } | |
5264 | |
5265 | |
5266 // Enter safepoint region | |
5267 // Beware of deadlocks such as 6317397. | |
5268 // The per-thread Parker:: mutex is a classic leaf-lock. | |
5269 // In particular a thread must never block on the Threads_lock while | |
5270 // holding the Parker:: mutex. If safepoints are pending both the | |
5271 // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock. | |
5272 ThreadBlockInVM tbivm(jt); | |
5273 | |
5274 // Don't wait if cannot get lock since interference arises from | |
5275 // unblocking. Also. check interrupt before trying wait | |
5276 if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) { | |
5277 return; | |
5278 } | |
5279 | |
5280 int status ; | |
5281 if (_counter > 0) { // no wait needed | |
5282 _counter = 0; | |
5283 status = pthread_mutex_unlock(_mutex); | |
5284 assert (status == 0, "invariant") ; | |
1117
95e9083cf4a7
6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents:
1010
diff
changeset
|
5285 OrderAccess::fence(); |
0 | 5286 return; |
5287 } | |
5288 | |
5289 #ifdef ASSERT | |
5290 // Don't catch signals while blocked; let the running threads have the signals. | |
5291 // (This allows a debugger to break into the running thread.) | |
5292 sigset_t oldsigs; | |
5293 sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals(); | |
5294 pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs); | |
5295 #endif | |
5296 | |
5297 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); | |
5298 jt->set_suspend_equivalent(); | |
5299 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() | |
5300 | |
5301 if (time == 0) { | |
5302 status = pthread_cond_wait (_cond, _mutex) ; | |
5303 } else { | |
5304 status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ; | |
5305 if (status != 0 && WorkAroundNPTLTimedWaitHang) { | |
5306 pthread_cond_destroy (_cond) ; | |
5307 pthread_cond_init (_cond, NULL); | |
5308 } | |
5309 } | |
5310 assert_status(status == 0 || status == EINTR || | |
5311 status == ETIME || status == ETIMEDOUT, | |
5312 status, "cond_timedwait"); | |
5313 | |
5314 #ifdef ASSERT | |
5315 pthread_sigmask(SIG_SETMASK, &oldsigs, NULL); | |
5316 #endif | |
5317 | |
5318 _counter = 0 ; | |
5319 status = pthread_mutex_unlock(_mutex) ; | |
5320 assert_status(status == 0, status, "invariant") ; | |
5321 // If externally suspended while waiting, re-suspend | |
5322 if (jt->handle_special_suspend_equivalent_condition()) { | |
5323 jt->java_suspend_self(); | |
5324 } | |
5325 | |
1117
95e9083cf4a7
6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents:
1010
diff
changeset
|
5326 OrderAccess::fence(); |
0 | 5327 } |
5328 | |
5329 void Parker::unpark() { | |
5330 int s, status ; | |
5331 status = pthread_mutex_lock(_mutex); | |
5332 assert (status == 0, "invariant") ; | |
5333 s = _counter; | |
5334 _counter = 1; | |
5335 if (s < 1) { | |
5336 if (WorkAroundNPTLTimedWaitHang) { | |
5337 status = pthread_cond_signal (_cond) ; | |
5338 assert (status == 0, "invariant") ; | |
5339 status = pthread_mutex_unlock(_mutex); | |
5340 assert (status == 0, "invariant") ; | |
5341 } else { | |
5342 status = pthread_mutex_unlock(_mutex); | |
5343 assert (status == 0, "invariant") ; | |
5344 status = pthread_cond_signal (_cond) ; | |
5345 assert (status == 0, "invariant") ; | |
5346 } | |
5347 } else { | |
5348 pthread_mutex_unlock(_mutex); | |
5349 assert (status == 0, "invariant") ; | |
5350 } | |
5351 } | |
5352 | |
5353 | |
5354 extern char** environ; | |
5355 | |
5356 #ifndef __NR_fork | |
5357 #define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57) | |
5358 #endif | |
5359 | |
5360 #ifndef __NR_execve | |
5361 #define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59) | |
5362 #endif | |
5363 | |
5364 // Run the specified command in a separate process. Return its exit value, | |
5365 // or -1 on failure (e.g. can't fork a new process). | |
5366 // Unlike system(), this function can be called from signal handler. It | |
5367 // doesn't block SIGINT et al. | |
5368 int os::fork_and_exec(char* cmd) { | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
5369 const char * argv[4] = {"sh", "-c", cmd, NULL}; |
0 | 5370 |
5371 // fork() in LinuxThreads/NPTL is not async-safe. It needs to run | |
5372 // pthread_atfork handlers and reset pthread library. All we need is a | |
5373 // separate process to execve. Make a direct syscall to fork process. | |
5374 // On IA64 there's no fork syscall, we have to use fork() and hope for | |
5375 // the best... | |
5376 pid_t pid = NOT_IA64(syscall(__NR_fork);) | |
5377 IA64_ONLY(fork();) | |
5378 | |
5379 if (pid < 0) { | |
5380 // fork failed | |
5381 return -1; | |
5382 | |
5383 } else if (pid == 0) { | |
5384 // child process | |
5385 | |
5386 // execve() in LinuxThreads will call pthread_kill_other_threads_np() | |
5387 // first to kill every thread on the thread list. Because this list is | |
5388 // not reset by fork() (see notes above), execve() will instead kill | |
5389 // every thread in the parent process. We know this is the only thread | |
5390 // in the new process, so make a system call directly. | |
5391 // IA64 should use normal execve() from glibc to match the glibc fork() | |
5392 // above. | |
5393 NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);) | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
5394 IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);) |
0 | 5395 |
5396 // execve failed | |
5397 _exit(-1); | |
5398 | |
5399 } else { | |
5400 // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't | |
5401 // care about the actual exit code, for now. | |
5402 | |
5403 int status; | |
5404 | |
5405 // Wait for the child process to exit. This returns immediately if | |
5406 // the child has already exited. */ | |
5407 while (waitpid(pid, &status, 0) < 0) { | |
5408 switch (errno) { | |
5409 case ECHILD: return 0; | |
5410 case EINTR: break; | |
5411 default: return -1; | |
5412 } | |
5413 } | |
5414 | |
5415 if (WIFEXITED(status)) { | |
5416 // The child exited normally; get its exit code. | |
5417 return WEXITSTATUS(status); | |
5418 } else if (WIFSIGNALED(status)) { | |
5419 // The child exited because of a signal | |
5420 // The best value to return is 0x80 + signal number, | |
5421 // because that is what all Unix shells do, and because | |
5422 // it allows callers to distinguish between process exit and | |
5423 // process death by signal. | |
5424 return 0x80 + WTERMSIG(status); | |
5425 } else { | |
5426 // Unknown exit code; pass it through | |
5427 return status; | |
5428 } | |
5429 } | |
5430 } | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5431 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5432 // is_headless_jre() |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5433 // |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
5434 // 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
|
5435 // 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
|
5436 // |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
5437 // 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
|
5438 // 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
|
5439 // |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5440 bool os::is_headless_jre() { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5441 struct stat statbuf; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5442 char buf[MAXPATHLEN]; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5443 char libmawtpath[MAXPATHLEN]; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5444 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
|
5445 const char *new_xawtstr = "/libawt_xawt.so"; |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5446 char *p; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5447 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5448 // Get path to libjvm.so |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5449 os::jvm_path(buf, sizeof(buf)); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5450 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5451 // Get rid of libjvm.so |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5452 p = strrchr(buf, '/'); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5453 if (p == NULL) return false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5454 else *p = '\0'; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5455 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5456 // Get rid of client or server |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5457 p = strrchr(buf, '/'); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5458 if (p == NULL) return false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5459 else *p = '\0'; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5460 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5461 // check xawt/libmawt.so |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5462 strcpy(libmawtpath, buf); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5463 strcat(libmawtpath, xawtstr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5464 if (::stat(libmawtpath, &statbuf) == 0) return false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5465 |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
5466 // check libawt_xawt.so |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5467 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
|
5468 strcat(libmawtpath, new_xawtstr); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5469 if (::stat(libmawtpath, &statbuf) == 0) return false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5470 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5471 return true; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5472 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5473 |
3802
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5474 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5475 #ifdef JAVASE_EMBEDDED |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5476 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5477 // A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory. |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5478 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5479 MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5480 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5481 // ctor |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5482 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5483 MemNotifyThread::MemNotifyThread(int fd): Thread() { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5484 assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread"); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5485 _fd = fd; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5486 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5487 if (os::create_thread(this, os::os_thread)) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5488 _memnotify_thread = this; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5489 os::set_priority(this, NearMaxPriority); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5490 os::start_thread(this); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5491 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5492 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5493 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5494 // Where all the work gets done |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5495 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5496 void MemNotifyThread::run() { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5497 assert(this == memnotify_thread(), "expected the singleton MemNotifyThread"); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5498 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5499 // Set up the select arguments |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5500 fd_set rfds; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5501 if (_fd != -1) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5502 FD_ZERO(&rfds); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5503 FD_SET(_fd, &rfds); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5504 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5505 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5506 // Now wait for the mem_notify device to wake up |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5507 while (1) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5508 // Wait for the mem_notify device to signal us.. |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5509 int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5510 if (rc == -1) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5511 perror("select!\n"); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5512 break; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5513 } else if (rc) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5514 //ssize_t free_before = os::available_memory(); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5515 //tty->print ("Notified: Free: %dK \n",os::available_memory()/1024); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5516 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5517 // The kernel is telling us there is not much memory left... |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5518 // try to do something about that |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5519 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5520 // If we are not already in a GC, try one. |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5521 if (!Universe::heap()->is_gc_active()) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5522 Universe::heap()->collect(GCCause::_allocation_failure); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5523 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5524 //ssize_t free_after = os::available_memory(); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5525 //tty->print ("Post-Notify: Free: %dK\n",free_after/1024); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5526 //tty->print ("GC freed: %dK\n", (free_after - free_before)/1024); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5527 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5528 // We might want to do something like the following if we find the GC's are not helping... |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5529 // Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5530 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5531 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5532 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5533 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5534 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5535 // See if the /dev/mem_notify device exists, and if so, start a thread to monitor it. |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5536 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5537 void MemNotifyThread::start() { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5538 int fd; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5539 fd = open ("/dev/mem_notify", O_RDONLY, 0); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5540 if (fd < 0) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5541 return; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5542 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5543 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5544 if (memnotify_thread() == NULL) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5545 new MemNotifyThread(fd); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5546 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5547 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
5548 #endif // JAVASE_EMBEDDED |