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