Mercurial > hg > truffle
annotate src/os/bsd/vm/os_bsd.cpp @ 8854:754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
Summary: Ergonomics now also takes available virtual memory into account when deciding for a heap size. The helper method to determine the maximum allocatable memory block now uses the appropriate OS specific calls to retrieve available virtual memory for the java process. In 32 bit environments this method now also searches for the maximum actually reservable amount of memory. Merge previously separate implementations for Linux/BSD/Solaris into a single method.
Reviewed-by: jmasa, tamao
author | tschatzl |
---|---|
date | Wed, 27 Mar 2013 19:21:18 +0100 |
parents | 252ad8d5f22b |
children | b9a918201d47 8be1318fbe77 |
rev | line source |
---|---|
3960 | 1 /* |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. |
3960 | 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 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
25 // no precompiled headers | |
26 #include "classfile/classLoader.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "classfile/vmSymbols.hpp" | |
29 #include "code/icBuffer.hpp" | |
30 #include "code/vtableStubs.hpp" | |
31 #include "compiler/compileBroker.hpp" | |
7199
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
6966
diff
changeset
|
32 #include "compiler/disassembler.hpp" |
3960 | 33 #include "interpreter/interpreter.hpp" |
34 #include "jvm_bsd.h" | |
35 #include "memory/allocation.inline.hpp" | |
36 #include "memory/filemap.hpp" | |
37 #include "mutex_bsd.inline.hpp" | |
38 #include "oops/oop.inline.hpp" | |
39 #include "os_share_bsd.hpp" | |
40 #include "prims/jniFastGetField.hpp" | |
41 #include "prims/jvm.h" | |
42 #include "prims/jvm_misc.hpp" | |
43 #include "runtime/arguments.hpp" | |
44 #include "runtime/extendedPC.hpp" | |
45 #include "runtime/globals.hpp" | |
46 #include "runtime/interfaceSupport.hpp" | |
47 #include "runtime/java.hpp" | |
48 #include "runtime/javaCalls.hpp" | |
49 #include "runtime/mutexLocker.hpp" | |
50 #include "runtime/objectMonitor.hpp" | |
51 #include "runtime/osThread.hpp" | |
52 #include "runtime/perfMemory.hpp" | |
53 #include "runtime/sharedRuntime.hpp" | |
54 #include "runtime/statSampler.hpp" | |
55 #include "runtime/stubRoutines.hpp" | |
7180
f34d701e952e
8003935: Simplify the needed includes for using Thread::current()
stefank
parents:
6966
diff
changeset
|
56 #include "runtime/thread.inline.hpp" |
3960 | 57 #include "runtime/threadCritical.hpp" |
58 #include "runtime/timer.hpp" | |
59 #include "services/attachListener.hpp" | |
8711
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
60 #include "services/memTracker.hpp" |
3960 | 61 #include "services/runtimeService.hpp" |
62 #include "utilities/decoder.hpp" | |
63 #include "utilities/defaultStream.hpp" | |
64 #include "utilities/events.hpp" | |
65 #include "utilities/growableArray.hpp" | |
66 #include "utilities/vmError.hpp" | |
67 | |
68 // put OS-includes here | |
69 # include <sys/types.h> | |
70 # include <sys/mman.h> | |
71 # include <sys/stat.h> | |
72 # include <sys/select.h> | |
73 # include <pthread.h> | |
74 # include <signal.h> | |
75 # include <errno.h> | |
76 # include <dlfcn.h> | |
77 # include <stdio.h> | |
78 # include <unistd.h> | |
79 # include <sys/resource.h> | |
80 # include <pthread.h> | |
81 # include <sys/stat.h> | |
82 # include <sys/time.h> | |
83 # include <sys/times.h> | |
84 # include <sys/utsname.h> | |
85 # include <sys/socket.h> | |
86 # include <sys/wait.h> | |
87 # include <time.h> | |
88 # include <pwd.h> | |
89 # include <poll.h> | |
90 # include <semaphore.h> | |
91 # include <fcntl.h> | |
92 # include <string.h> | |
93 # include <sys/param.h> | |
94 # include <sys/sysctl.h> | |
95 # include <sys/ipc.h> | |
96 # include <sys/shm.h> | |
97 #ifndef __APPLE__ | |
98 # include <link.h> | |
99 #endif | |
100 # include <stdint.h> | |
101 # include <inttypes.h> | |
102 # include <sys/ioctl.h> | |
103 | |
104 #if defined(__FreeBSD__) || defined(__NetBSD__) | |
105 # include <elf.h> | |
106 #endif | |
107 | |
108 #ifdef __APPLE__ | |
4006 | 109 # include <mach/mach.h> // semaphore_* API |
110 # include <mach-o/dyld.h> | |
111 # include <sys/proc_info.h> | |
112 # include <objc/objc-auto.h> | |
3960 | 113 #endif |
114 | |
115 #ifndef MAP_ANONYMOUS | |
116 #define MAP_ANONYMOUS MAP_ANON | |
117 #endif | |
118 | |
119 #define MAX_PATH (2 * K) | |
120 | |
121 // for timer info max values which include all bits | |
122 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) | |
123 | |
124 #define LARGEPAGES_BIT (1 << 6) | |
125 //////////////////////////////////////////////////////////////////////////////// | |
126 // global variables | |
127 julong os::Bsd::_physical_memory = 0; | |
128 | |
129 | |
130 int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL; | |
131 pthread_t os::Bsd::_main_thread; | |
132 int os::Bsd::_page_size = -1; | |
133 | |
134 static jlong initial_time_count=0; | |
135 | |
136 static int clock_tics_per_sec = 100; | |
137 | |
138 // For diagnostics to print a message once. see run_periodic_checks | |
139 static sigset_t check_signal_done; | |
6918 | 140 static bool check_signals = true; |
3960 | 141 |
142 static pid_t _initial_pid = 0; | |
143 | |
144 /* Signal number used to suspend/resume a thread */ | |
145 | |
146 /* do not use any signal number less than SIGSEGV, see 4355769 */ | |
147 static int SR_signum = SIGUSR2; | |
148 sigset_t SR_sigset; | |
149 | |
150 | |
151 //////////////////////////////////////////////////////////////////////////////// | |
152 // utility functions | |
153 | |
154 static int SR_initialize(); | |
155 static int SR_finalize(); | |
156 | |
157 julong os::available_memory() { | |
158 return Bsd::available_memory(); | |
159 } | |
160 | |
161 julong os::Bsd::available_memory() { | |
162 // XXXBSD: this is just a stopgap implementation | |
163 return physical_memory() >> 2; | |
164 } | |
165 | |
166 julong os::physical_memory() { | |
167 return Bsd::physical_memory(); | |
168 } | |
169 | |
170 //////////////////////////////////////////////////////////////////////////////// | |
171 // environment support | |
172 | |
173 bool os::getenv(const char* name, char* buf, int len) { | |
174 const char* val = ::getenv(name); | |
175 if (val != NULL && strlen(val) < (size_t)len) { | |
176 strcpy(buf, val); | |
177 return true; | |
178 } | |
179 if (len > 0) buf[0] = 0; // return a null string | |
180 return false; | |
181 } | |
182 | |
183 | |
184 // Return true if user is running as root. | |
185 | |
186 bool os::have_special_privileges() { | |
187 static bool init = false; | |
188 static bool privileges = false; | |
189 if (!init) { | |
190 privileges = (getuid() != geteuid()) || (getgid() != getegid()); | |
191 init = true; | |
192 } | |
193 return privileges; | |
194 } | |
195 | |
196 | |
197 | |
198 // Cpu architecture string | |
199 #if defined(ZERO) | |
200 static char cpu_arch[] = ZERO_LIBARCH; | |
201 #elif defined(IA64) | |
202 static char cpu_arch[] = "ia64"; | |
203 #elif defined(IA32) | |
204 static char cpu_arch[] = "i386"; | |
205 #elif defined(AMD64) | |
206 static char cpu_arch[] = "amd64"; | |
207 #elif defined(ARM) | |
208 static char cpu_arch[] = "arm"; | |
209 #elif defined(PPC) | |
210 static char cpu_arch[] = "ppc"; | |
211 #elif defined(SPARC) | |
212 # ifdef _LP64 | |
213 static char cpu_arch[] = "sparcv9"; | |
214 # else | |
215 static char cpu_arch[] = "sparc"; | |
216 # endif | |
217 #else | |
218 #error Add appropriate cpu_arch setting | |
219 #endif | |
220 | |
4846 | 221 // Compiler variant |
222 #ifdef COMPILER2 | |
223 #define COMPILER_VARIANT "server" | |
224 #else | |
225 #define COMPILER_VARIANT "client" | |
226 #endif | |
3960 | 227 |
6918 | 228 |
3960 | 229 void os::Bsd::initialize_system_info() { |
230 int mib[2]; | |
231 size_t len; | |
232 int cpu_val; | |
7626
c07c102cbad7
8006431: os::Bsd::initialize_system_info() sets _physical_memory too large
brutisso
parents:
7456
diff
changeset
|
233 julong mem_val; |
3960 | 234 |
235 /* get processors count via hw.ncpus sysctl */ | |
236 mib[0] = CTL_HW; | |
237 mib[1] = HW_NCPU; | |
238 len = sizeof(cpu_val); | |
239 if (sysctl(mib, 2, &cpu_val, &len, NULL, 0) != -1 && cpu_val >= 1) { | |
7626
c07c102cbad7
8006431: os::Bsd::initialize_system_info() sets _physical_memory too large
brutisso
parents:
7456
diff
changeset
|
240 assert(len == sizeof(cpu_val), "unexpected data size"); |
3960 | 241 set_processor_count(cpu_val); |
242 } | |
243 else { | |
244 set_processor_count(1); // fallback | |
245 } | |
246 | |
7626
c07c102cbad7
8006431: os::Bsd::initialize_system_info() sets _physical_memory too large
brutisso
parents:
7456
diff
changeset
|
247 /* get physical memory via hw.memsize sysctl (hw.memsize is used |
c07c102cbad7
8006431: os::Bsd::initialize_system_info() sets _physical_memory too large
brutisso
parents:
7456
diff
changeset
|
248 * since it returns a 64 bit value) |
3960 | 249 */ |
250 mib[0] = CTL_HW; | |
7626
c07c102cbad7
8006431: os::Bsd::initialize_system_info() sets _physical_memory too large
brutisso
parents:
7456
diff
changeset
|
251 mib[1] = HW_MEMSIZE; |
3960 | 252 len = sizeof(mem_val); |
7626
c07c102cbad7
8006431: os::Bsd::initialize_system_info() sets _physical_memory too large
brutisso
parents:
7456
diff
changeset
|
253 if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1) { |
c07c102cbad7
8006431: os::Bsd::initialize_system_info() sets _physical_memory too large
brutisso
parents:
7456
diff
changeset
|
254 assert(len == sizeof(mem_val), "unexpected data size"); |
3960 | 255 _physical_memory = mem_val; |
7626
c07c102cbad7
8006431: os::Bsd::initialize_system_info() sets _physical_memory too large
brutisso
parents:
7456
diff
changeset
|
256 } else { |
3960 | 257 _physical_memory = 256*1024*1024; // fallback (XXXBSD?) |
7626
c07c102cbad7
8006431: os::Bsd::initialize_system_info() sets _physical_memory too large
brutisso
parents:
7456
diff
changeset
|
258 } |
3960 | 259 |
260 #ifdef __OpenBSD__ | |
261 { | |
262 // limit _physical_memory memory view on OpenBSD since | |
263 // datasize rlimit restricts us anyway. | |
264 struct rlimit limits; | |
265 getrlimit(RLIMIT_DATA, &limits); | |
266 _physical_memory = MIN2(_physical_memory, (julong)limits.rlim_cur); | |
267 } | |
268 #endif | |
269 } | |
270 | |
4006 | 271 #ifdef __APPLE__ |
272 static const char *get_home() { | |
273 const char *home_dir = ::getenv("HOME"); | |
274 if ((home_dir == NULL) || (*home_dir == '\0')) { | |
275 struct passwd *passwd_info = getpwuid(geteuid()); | |
276 if (passwd_info != NULL) { | |
277 home_dir = passwd_info->pw_dir; | |
278 } | |
279 } | |
280 | |
281 return home_dir; | |
282 } | |
283 #endif | |
284 | |
3960 | 285 void os::init_system_properties_values() { |
286 // char arch[12]; | |
287 // sysinfo(SI_ARCHITECTURE, arch, sizeof(arch)); | |
288 | |
289 // The next steps are taken in the product version: | |
290 // | |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
291 // Obtain the JAVA_HOME value from the location of libjvm.so. |
3960 | 292 // This library should be located at: |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
293 // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm.so. |
3960 | 294 // |
295 // If "/jre/lib/" appears at the right place in the path, then we | |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
296 // assume libjvm.so is installed in a JDK and we use this path. |
3960 | 297 // |
298 // Otherwise exit with message: "Could not create the Java virtual machine." | |
299 // | |
300 // The following extra steps are taken in the debugging version: | |
301 // | |
302 // If "/jre/lib/" does NOT appear at the right place in the path | |
303 // instead of exit check for $JAVA_HOME environment variable. | |
304 // | |
305 // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>, | |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
306 // then we append a fake suffix "hotspot/libjvm.so" to this path so |
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
307 // it looks like libjvm.so is installed there |
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
308 // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so. |
3960 | 309 // |
310 // Otherwise exit. | |
311 // | |
312 // Important note: if the location of libjvm.so changes this | |
313 // code needs to be changed accordingly. | |
314 | |
315 // The next few definitions allow the code to be verbatim: | |
6197 | 316 #define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal) |
3960 | 317 #define getenv(n) ::getenv(n) |
318 | |
319 /* | |
320 * See ld(1): | |
321 * The linker uses the following search paths to locate required | |
322 * shared libraries: | |
323 * 1: ... | |
324 * ... | |
325 * 7: The default directories, normally /lib and /usr/lib. | |
326 */ | |
327 #ifndef DEFAULT_LIBPATH | |
328 #define DEFAULT_LIBPATH "/lib:/usr/lib" | |
329 #endif | |
330 | |
331 #define EXTENSIONS_DIR "/lib/ext" | |
332 #define ENDORSED_DIR "/lib/endorsed" | |
333 #define REG_DIR "/usr/java/packages" | |
334 | |
4006 | 335 #ifdef __APPLE__ |
336 #define SYS_EXTENSIONS_DIR "/Library/Java/Extensions" | |
337 #define SYS_EXTENSIONS_DIRS SYS_EXTENSIONS_DIR ":/Network" SYS_EXTENSIONS_DIR ":/System" SYS_EXTENSIONS_DIR ":/usr/lib/java" | |
338 const char *user_home_dir = get_home(); | |
339 // the null in SYS_EXTENSIONS_DIRS counts for the size of the colon after user_home_dir | |
340 int system_ext_size = strlen(user_home_dir) + sizeof(SYS_EXTENSIONS_DIR) + | |
341 sizeof(SYS_EXTENSIONS_DIRS); | |
342 #endif | |
343 | |
3960 | 344 { |
345 /* sysclasspath, java_home, dll_dir */ | |
346 { | |
347 char *home_path; | |
348 char *dll_path; | |
349 char *pslash; | |
350 char buf[MAXPATHLEN]; | |
351 os::jvm_path(buf, sizeof(buf)); | |
352 | |
353 // Found the full path to libjvm.so. | |
354 // Now cut the path to <java_home>/jre if we can. | |
355 *(strrchr(buf, '/')) = '\0'; /* get rid of /libjvm.so */ | |
356 pslash = strrchr(buf, '/'); | |
357 if (pslash != NULL) | |
358 *pslash = '\0'; /* get rid of /{client|server|hotspot} */ | |
359 dll_path = malloc(strlen(buf) + 1); | |
360 if (dll_path == NULL) | |
361 return; | |
362 strcpy(dll_path, buf); | |
363 Arguments::set_dll_dir(dll_path); | |
364 | |
365 if (pslash != NULL) { | |
366 pslash = strrchr(buf, '/'); | |
367 if (pslash != NULL) { | |
4006 | 368 *pslash = '\0'; /* get rid of /<arch> (/lib on macosx) */ |
369 #ifndef __APPLE__ | |
3960 | 370 pslash = strrchr(buf, '/'); |
371 if (pslash != NULL) | |
372 *pslash = '\0'; /* get rid of /lib */ | |
4006 | 373 #endif |
3960 | 374 } |
375 } | |
376 | |
377 home_path = malloc(strlen(buf) + 1); | |
378 if (home_path == NULL) | |
379 return; | |
380 strcpy(home_path, buf); | |
381 Arguments::set_java_home(home_path); | |
382 | |
383 if (!set_boot_path('/', ':')) | |
384 return; | |
385 } | |
386 | |
387 /* | |
388 * Where to look for native libraries | |
389 * | |
390 * Note: Due to a legacy implementation, most of the library path | |
391 * is set in the launcher. This was to accomodate linking restrictions | |
392 * on legacy Bsd implementations (which are no longer supported). | |
393 * Eventually, all the library path setting will be done here. | |
394 * | |
395 * However, to prevent the proliferation of improperly built native | |
396 * libraries, the new path component /usr/java/packages is added here. | |
397 * Eventually, all the library path setting will be done here. | |
398 */ | |
399 { | |
400 char *ld_library_path; | |
401 | |
402 /* | |
403 * Construct the invariant part of ld_library_path. Note that the | |
404 * space for the colon and the trailing null are provided by the | |
405 * nulls included by the sizeof operator (so actually we allocate | |
406 * a byte more than necessary). | |
407 */ | |
4006 | 408 #ifdef __APPLE__ |
409 ld_library_path = (char *) malloc(system_ext_size); | |
410 sprintf(ld_library_path, "%s" SYS_EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS, user_home_dir); | |
411 #else | |
3960 | 412 ld_library_path = (char *) malloc(sizeof(REG_DIR) + sizeof("/lib/") + |
413 strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH)); | |
414 sprintf(ld_library_path, REG_DIR "/lib/%s:" DEFAULT_LIBPATH, cpu_arch); | |
4006 | 415 #endif |
3960 | 416 |
417 /* | |
418 * Get the user setting of LD_LIBRARY_PATH, and prepended it. It | |
419 * should always exist (until the legacy problem cited above is | |
420 * addressed). | |
421 */ | |
422 #ifdef __APPLE__ | |
4006 | 423 // Prepend the default path with the JAVA_LIBRARY_PATH so that the app launcher code can specify a directory inside an app wrapper |
424 char *l = getenv("JAVA_LIBRARY_PATH"); | |
425 if (l != NULL) { | |
426 char *t = ld_library_path; | |
427 /* That's +1 for the colon and +1 for the trailing '\0' */ | |
428 ld_library_path = (char *) malloc(strlen(l) + 1 + strlen(t) + 1); | |
429 sprintf(ld_library_path, "%s:%s", l, t); | |
430 free(t); | |
431 } | |
432 | |
3960 | 433 char *v = getenv("DYLD_LIBRARY_PATH"); |
434 #else | |
435 char *v = getenv("LD_LIBRARY_PATH"); | |
436 #endif | |
437 if (v != NULL) { | |
438 char *t = ld_library_path; | |
439 /* That's +1 for the colon and +1 for the trailing '\0' */ | |
440 ld_library_path = (char *) malloc(strlen(v) + 1 + strlen(t) + 1); | |
441 sprintf(ld_library_path, "%s:%s", v, t); | |
4006 | 442 free(t); |
3960 | 443 } |
4960
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
444 |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
445 #ifdef __APPLE__ |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
446 // Apple's Java6 has "." at the beginning of java.library.path. |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
447 // OpenJDK on Windows has "." at the end of java.library.path. |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
448 // OpenJDK on Linux and Solaris don't have "." in java.library.path |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
449 // at all. To ease the transition from Apple's Java6 to OpenJDK7, |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
450 // "." is appended to the end of java.library.path. Yes, this |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
451 // could cause a change in behavior, but Apple's Java6 behavior |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
452 // can be achieved by putting "." at the beginning of the |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
453 // JAVA_LIBRARY_PATH environment variable. |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
454 { |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
455 char *t = ld_library_path; |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
456 // that's +3 for appending ":." and the trailing '\0' |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
457 ld_library_path = (char *) malloc(strlen(t) + 3); |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
458 sprintf(ld_library_path, "%s:%s", t, "."); |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
459 free(t); |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
460 } |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
461 #endif |
86ce3208eb18
7145798: System.loadLibrary does not search current working directory
dcubed
parents:
4854
diff
changeset
|
462 |
3960 | 463 Arguments::set_library_path(ld_library_path); |
464 } | |
465 | |
466 /* | |
467 * Extensions directories. | |
468 * | |
469 * Note that the space for the colon and the trailing null are provided | |
470 * by the nulls included by the sizeof operator (so actually one byte more | |
471 * than necessary is allocated). | |
472 */ | |
473 { | |
4006 | 474 #ifdef __APPLE__ |
475 char *buf = malloc(strlen(Arguments::get_java_home()) + | |
476 sizeof(EXTENSIONS_DIR) + system_ext_size); | |
477 sprintf(buf, "%s" SYS_EXTENSIONS_DIR ":%s" EXTENSIONS_DIR ":" | |
478 SYS_EXTENSIONS_DIRS, user_home_dir, Arguments::get_java_home()); | |
479 #else | |
3960 | 480 char *buf = malloc(strlen(Arguments::get_java_home()) + |
481 sizeof(EXTENSIONS_DIR) + sizeof(REG_DIR) + sizeof(EXTENSIONS_DIR)); | |
482 sprintf(buf, "%s" EXTENSIONS_DIR ":" REG_DIR EXTENSIONS_DIR, | |
483 Arguments::get_java_home()); | |
4006 | 484 #endif |
485 | |
3960 | 486 Arguments::set_ext_dirs(buf); |
487 } | |
488 | |
489 /* Endorsed standards default directory. */ | |
490 { | |
491 char * buf; | |
492 buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR)); | |
493 sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home()); | |
494 Arguments::set_endorsed_dirs(buf); | |
495 } | |
496 } | |
497 | |
4006 | 498 #ifdef __APPLE__ |
499 #undef SYS_EXTENSIONS_DIR | |
500 #endif | |
3960 | 501 #undef malloc |
502 #undef getenv | |
503 #undef EXTENSIONS_DIR | |
504 #undef ENDORSED_DIR | |
505 | |
506 // Done | |
507 return; | |
508 } | |
509 | |
510 //////////////////////////////////////////////////////////////////////////////// | |
511 // breakpoint support | |
512 | |
513 void os::breakpoint() { | |
514 BREAKPOINT; | |
515 } | |
516 | |
517 extern "C" void breakpoint() { | |
518 // use debugger to set breakpoint here | |
519 } | |
520 | |
521 //////////////////////////////////////////////////////////////////////////////// | |
522 // signal support | |
523 | |
524 debug_only(static bool signal_sets_initialized = false); | |
525 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs; | |
526 | |
527 bool os::Bsd::is_sig_ignored(int sig) { | |
528 struct sigaction oact; | |
529 sigaction(sig, (struct sigaction*)NULL, &oact); | |
530 void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction) | |
531 : CAST_FROM_FN_PTR(void*, oact.sa_handler); | |
532 if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) | |
533 return true; | |
534 else | |
535 return false; | |
536 } | |
537 | |
538 void os::Bsd::signal_sets_init() { | |
539 // Should also have an assertion stating we are still single-threaded. | |
540 assert(!signal_sets_initialized, "Already initialized"); | |
541 // Fill in signals that are necessarily unblocked for all threads in | |
542 // the VM. Currently, we unblock the following signals: | |
543 // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden | |
544 // by -Xrs (=ReduceSignalUsage)); | |
545 // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all | |
546 // other threads. The "ReduceSignalUsage" boolean tells us not to alter | |
547 // the dispositions or masks wrt these signals. | |
548 // Programs embedding the VM that want to use the above signals for their | |
549 // own purposes must, at this time, use the "-Xrs" option to prevent | |
550 // interference with shutdown hooks and BREAK_SIGNAL thread dumping. | |
551 // (See bug 4345157, and other related bugs). | |
552 // In reality, though, unblocking these signals is really a nop, since | |
553 // these signals are not blocked by default. | |
554 sigemptyset(&unblocked_sigs); | |
555 sigemptyset(&allowdebug_blocked_sigs); | |
556 sigaddset(&unblocked_sigs, SIGILL); | |
557 sigaddset(&unblocked_sigs, SIGSEGV); | |
558 sigaddset(&unblocked_sigs, SIGBUS); | |
559 sigaddset(&unblocked_sigs, SIGFPE); | |
560 sigaddset(&unblocked_sigs, SR_signum); | |
561 | |
562 if (!ReduceSignalUsage) { | |
563 if (!os::Bsd::is_sig_ignored(SHUTDOWN1_SIGNAL)) { | |
564 sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL); | |
565 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL); | |
566 } | |
567 if (!os::Bsd::is_sig_ignored(SHUTDOWN2_SIGNAL)) { | |
568 sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL); | |
569 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL); | |
570 } | |
571 if (!os::Bsd::is_sig_ignored(SHUTDOWN3_SIGNAL)) { | |
572 sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL); | |
573 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL); | |
574 } | |
575 } | |
576 // Fill in signals that are blocked by all but the VM thread. | |
577 sigemptyset(&vm_sigs); | |
578 if (!ReduceSignalUsage) | |
579 sigaddset(&vm_sigs, BREAK_SIGNAL); | |
580 debug_only(signal_sets_initialized = true); | |
581 | |
582 } | |
583 | |
584 // These are signals that are unblocked while a thread is running Java. | |
585 // (For some reason, they get blocked by default.) | |
586 sigset_t* os::Bsd::unblocked_signals() { | |
587 assert(signal_sets_initialized, "Not initialized"); | |
588 return &unblocked_sigs; | |
589 } | |
590 | |
591 // These are the signals that are blocked while a (non-VM) thread is | |
592 // running Java. Only the VM thread handles these signals. | |
593 sigset_t* os::Bsd::vm_signals() { | |
594 assert(signal_sets_initialized, "Not initialized"); | |
595 return &vm_sigs; | |
596 } | |
597 | |
598 // These are signals that are blocked during cond_wait to allow debugger in | |
599 sigset_t* os::Bsd::allowdebug_blocked_signals() { | |
600 assert(signal_sets_initialized, "Not initialized"); | |
601 return &allowdebug_blocked_sigs; | |
602 } | |
603 | |
604 void os::Bsd::hotspot_sigmask(Thread* thread) { | |
605 | |
606 //Save caller's signal mask before setting VM signal mask | |
607 sigset_t caller_sigmask; | |
608 pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask); | |
609 | |
610 OSThread* osthread = thread->osthread(); | |
611 osthread->set_caller_sigmask(caller_sigmask); | |
612 | |
613 pthread_sigmask(SIG_UNBLOCK, os::Bsd::unblocked_signals(), NULL); | |
614 | |
615 if (!ReduceSignalUsage) { | |
616 if (thread->is_VM_thread()) { | |
617 // Only the VM thread handles BREAK_SIGNAL ... | |
618 pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL); | |
619 } else { | |
620 // ... all other threads block BREAK_SIGNAL | |
621 pthread_sigmask(SIG_BLOCK, vm_signals(), NULL); | |
622 } | |
623 } | |
624 } | |
625 | |
626 | |
627 ////////////////////////////////////////////////////////////////////////////// | |
628 // create new thread | |
629 | |
630 static address highest_vm_reserved_address(); | |
631 | |
632 // check if it's safe to start a new thread | |
633 static bool _thread_safety_check(Thread* thread) { | |
6918 | 634 return true; |
3960 | 635 } |
636 | |
4006 | 637 #ifdef __APPLE__ |
638 // library handle for calling objc_registerThreadWithCollector() | |
639 // without static linking to the libobjc library | |
640 #define OBJC_LIB "/usr/lib/libobjc.dylib" | |
641 #define OBJC_GCREGISTER "objc_registerThreadWithCollector" | |
642 typedef void (*objc_registerThreadWithCollector_t)(); | |
643 extern "C" objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction; | |
644 objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction = NULL; | |
645 #endif | |
646 | |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
647 #ifdef __APPLE__ |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
648 static uint64_t locate_unique_thread_id() { |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
649 // Additional thread_id used to correlate threads in SA |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
650 thread_identifier_info_data_t m_ident_info; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
651 mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
652 |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
653 thread_info(::mach_thread_self(), THREAD_IDENTIFIER_INFO, |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
654 (thread_info_t) &m_ident_info, &count); |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
655 return m_ident_info.thread_id; |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
656 } |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
657 #endif |
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
658 |
3960 | 659 // Thread start routine for all newly created threads |
660 static void *java_start(Thread *thread) { | |
661 // Try to randomize the cache line index of hot stack frames. | |
662 // This helps when threads of the same stack traces evict each other's | |
663 // cache lines. The threads can be either from the same JVM instance, or | |
664 // from different JVM instances. The benefit is especially true for | |
665 // processors with hyperthreading technology. | |
666 static int counter = 0; | |
667 int pid = os::current_process_id(); | |
668 alloca(((pid ^ counter++) & 7) * 128); | |
669 | |
670 ThreadLocalStorage::set_thread(thread); | |
671 | |
672 OSThread* osthread = thread->osthread(); | |
673 Monitor* sync = osthread->startThread_lock(); | |
674 | |
675 // non floating stack BsdThreads needs extra check, see above | |
676 if (!_thread_safety_check(thread)) { | |
677 // notify parent thread | |
678 MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); | |
679 osthread->set_state(ZOMBIE); | |
680 sync->notify_all(); | |
681 return NULL; | |
682 } | |
683 | |
4961
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
684 #ifdef __APPLE__ |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
685 // thread_id is mach thread on macos |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
686 osthread->set_thread_id(::mach_thread_self()); |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
687 osthread->set_unique_thread_id(locate_unique_thread_id()); |
4961
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
688 #else |
3960 | 689 // thread_id is pthread_id on BSD |
690 osthread->set_thread_id(::pthread_self()); | |
4961
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
691 #endif |
3960 | 692 // initialize signal mask for this thread |
693 os::Bsd::hotspot_sigmask(thread); | |
694 | |
695 // initialize floating point control register | |
696 os::Bsd::init_thread_fpu_state(); | |
697 | |
4006 | 698 #ifdef __APPLE__ |
699 // register thread with objc gc | |
700 if (objc_registerThreadWithCollectorFunction != NULL) { | |
701 objc_registerThreadWithCollectorFunction(); | |
702 } | |
703 #endif | |
704 | |
3960 | 705 // handshaking with parent thread |
706 { | |
707 MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); | |
708 | |
709 // notify parent thread | |
710 osthread->set_state(INITIALIZED); | |
711 sync->notify_all(); | |
712 | |
713 // wait until os::start_thread() | |
714 while (osthread->get_state() == INITIALIZED) { | |
715 sync->wait(Mutex::_no_safepoint_check_flag); | |
716 } | |
717 } | |
718 | |
719 // call one more level start routine | |
720 thread->run(); | |
721 | |
722 return 0; | |
723 } | |
724 | |
725 bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { | |
726 assert(thread->osthread() == NULL, "caller responsible"); | |
727 | |
728 // Allocate the OSThread object | |
729 OSThread* osthread = new OSThread(NULL, NULL); | |
730 if (osthread == NULL) { | |
731 return false; | |
732 } | |
733 | |
734 // set the correct thread state | |
735 osthread->set_thread_type(thr_type); | |
736 | |
737 // Initial state is ALLOCATED but not INITIALIZED | |
738 osthread->set_state(ALLOCATED); | |
739 | |
740 thread->set_osthread(osthread); | |
741 | |
742 // init thread attributes | |
743 pthread_attr_t attr; | |
744 pthread_attr_init(&attr); | |
745 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
746 | |
747 // stack size | |
748 if (os::Bsd::supports_variable_stack_size()) { | |
749 // calculate stack size if it's not specified by caller | |
750 if (stack_size == 0) { | |
751 stack_size = os::Bsd::default_stack_size(thr_type); | |
752 | |
753 switch (thr_type) { | |
754 case os::java_thread: | |
755 // Java threads use ThreadStackSize which default value can be | |
756 // changed with the flag -Xss | |
757 assert (JavaThread::stack_size_at_create() > 0, "this should be set"); | |
758 stack_size = JavaThread::stack_size_at_create(); | |
759 break; | |
760 case os::compiler_thread: | |
761 if (CompilerThreadStackSize > 0) { | |
762 stack_size = (size_t)(CompilerThreadStackSize * K); | |
763 break; | |
764 } // else fall through: | |
765 // use VMThreadStackSize if CompilerThreadStackSize is not defined | |
766 case os::vm_thread: | |
767 case os::pgc_thread: | |
768 case os::cgc_thread: | |
769 case os::watcher_thread: | |
770 if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K); | |
771 break; | |
772 } | |
773 } | |
774 | |
775 stack_size = MAX2(stack_size, os::Bsd::min_stack_allowed); | |
776 pthread_attr_setstacksize(&attr, stack_size); | |
777 } else { | |
778 // let pthread_create() pick the default value. | |
779 } | |
780 | |
781 ThreadState state; | |
782 | |
783 { | |
784 pthread_t tid; | |
785 int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); | |
786 | |
787 pthread_attr_destroy(&attr); | |
788 | |
789 if (ret != 0) { | |
790 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
791 perror("pthread_create()"); | |
792 } | |
793 // Need to clean up stuff we've allocated so far | |
794 thread->set_osthread(NULL); | |
795 delete osthread; | |
796 return false; | |
797 } | |
798 | |
799 // Store pthread info into the OSThread | |
800 osthread->set_pthread_id(tid); | |
801 | |
802 // Wait until child thread is either initialized or aborted | |
803 { | |
804 Monitor* sync_with_child = osthread->startThread_lock(); | |
805 MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag); | |
806 while ((state = osthread->get_state()) == ALLOCATED) { | |
807 sync_with_child->wait(Mutex::_no_safepoint_check_flag); | |
808 } | |
809 } | |
810 | |
811 } | |
812 | |
813 // Aborted due to thread limit being reached | |
814 if (state == ZOMBIE) { | |
815 thread->set_osthread(NULL); | |
816 delete osthread; | |
817 return false; | |
818 } | |
819 | |
820 // The thread is returned suspended (in state INITIALIZED), | |
821 // and is started higher up in the call chain | |
822 assert(state == INITIALIZED, "race condition"); | |
823 return true; | |
824 } | |
825 | |
826 ///////////////////////////////////////////////////////////////////////////// | |
827 // attach existing thread | |
828 | |
829 // bootstrap the main thread | |
830 bool os::create_main_thread(JavaThread* thread) { | |
831 assert(os::Bsd::_main_thread == pthread_self(), "should be called inside main thread"); | |
832 return create_attached_thread(thread); | |
833 } | |
834 | |
835 bool os::create_attached_thread(JavaThread* thread) { | |
836 #ifdef ASSERT | |
837 thread->verify_not_published(); | |
838 #endif | |
839 | |
840 // Allocate the OSThread object | |
841 OSThread* osthread = new OSThread(NULL, NULL); | |
842 | |
843 if (osthread == NULL) { | |
844 return false; | |
845 } | |
846 | |
847 // Store pthread info into the OSThread | |
4961
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
848 #ifdef __APPLE__ |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
849 osthread->set_thread_id(::mach_thread_self()); |
8023
758935f7c23f
8006423: SA: NullPointerException in sun.jvm.hotspot.debugger.bsd.BsdThread.getContext(BsdThread.java:67)
sla
parents:
7629
diff
changeset
|
850 osthread->set_unique_thread_id(locate_unique_thread_id()); |
4961
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
851 #else |
3960 | 852 osthread->set_thread_id(::pthread_self()); |
4961
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
853 #endif |
3960 | 854 osthread->set_pthread_id(::pthread_self()); |
855 | |
856 // initialize floating point control register | |
857 os::Bsd::init_thread_fpu_state(); | |
858 | |
859 // Initial thread state is RUNNABLE | |
860 osthread->set_state(RUNNABLE); | |
861 | |
862 thread->set_osthread(osthread); | |
863 | |
864 // initialize signal mask for this thread | |
865 // and save the caller's signal mask | |
866 os::Bsd::hotspot_sigmask(thread); | |
867 | |
868 return true; | |
869 } | |
870 | |
871 void os::pd_start_thread(Thread* thread) { | |
872 OSThread * osthread = thread->osthread(); | |
873 assert(osthread->get_state() != INITIALIZED, "just checking"); | |
874 Monitor* sync_with_child = osthread->startThread_lock(); | |
875 MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag); | |
876 sync_with_child->notify(); | |
877 } | |
878 | |
879 // Free Bsd resources related to the OSThread | |
880 void os::free_thread(OSThread* osthread) { | |
881 assert(osthread != NULL, "osthread not set"); | |
882 | |
883 if (Thread::current()->osthread() == osthread) { | |
884 // Restore caller's signal mask | |
885 sigset_t sigmask = osthread->caller_sigmask(); | |
886 pthread_sigmask(SIG_SETMASK, &sigmask, NULL); | |
887 } | |
888 | |
889 delete osthread; | |
890 } | |
891 | |
892 ////////////////////////////////////////////////////////////////////////////// | |
893 // thread local storage | |
894 | |
895 int os::allocate_thread_local_storage() { | |
896 pthread_key_t key; | |
897 int rslt = pthread_key_create(&key, NULL); | |
898 assert(rslt == 0, "cannot allocate thread local storage"); | |
899 return (int)key; | |
900 } | |
901 | |
902 // Note: This is currently not used by VM, as we don't destroy TLS key | |
903 // on VM exit. | |
904 void os::free_thread_local_storage(int index) { | |
905 int rslt = pthread_key_delete((pthread_key_t)index); | |
906 assert(rslt == 0, "invalid index"); | |
907 } | |
908 | |
909 void os::thread_local_storage_at_put(int index, void* value) { | |
910 int rslt = pthread_setspecific((pthread_key_t)index, value); | |
911 assert(rslt == 0, "pthread_setspecific failed"); | |
912 } | |
913 | |
914 extern "C" Thread* get_thread() { | |
915 return ThreadLocalStorage::thread(); | |
916 } | |
917 | |
918 | |
919 //////////////////////////////////////////////////////////////////////////////// | |
920 // time support | |
921 | |
922 // Time since start-up in seconds to a fine granularity. | |
923 // Used by VMSelfDestructTimer and the MemProfiler. | |
924 double os::elapsedTime() { | |
925 | |
926 return (double)(os::elapsed_counter()) * 0.000001; | |
927 } | |
928 | |
929 jlong os::elapsed_counter() { | |
930 timeval time; | |
931 int status = gettimeofday(&time, NULL); | |
932 return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count; | |
933 } | |
934 | |
935 jlong os::elapsed_frequency() { | |
936 return (1000 * 1000); | |
937 } | |
938 | |
939 // XXX: For now, code this as if BSD does not support vtime. | |
940 bool os::supports_vtime() { return false; } | |
941 bool os::enable_vtime() { return false; } | |
942 bool os::vtime_enabled() { return false; } | |
943 double os::elapsedVTime() { | |
944 // better than nothing, but not much | |
945 return elapsedTime(); | |
946 } | |
947 | |
948 jlong os::javaTimeMillis() { | |
949 timeval time; | |
950 int status = gettimeofday(&time, NULL); | |
951 assert(status != -1, "bsd error"); | |
952 return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); | |
953 } | |
954 | |
955 #ifndef CLOCK_MONOTONIC | |
956 #define CLOCK_MONOTONIC (1) | |
957 #endif | |
958 | |
959 #ifdef __APPLE__ | |
960 void os::Bsd::clock_init() { | |
961 // XXXDARWIN: Investigate replacement monotonic clock | |
962 } | |
6918 | 963 #else |
3960 | 964 void os::Bsd::clock_init() { |
965 struct timespec res; | |
966 struct timespec tp; | |
967 if (::clock_getres(CLOCK_MONOTONIC, &res) == 0 && | |
968 ::clock_gettime(CLOCK_MONOTONIC, &tp) == 0) { | |
969 // yes, monotonic clock is supported | |
970 _clock_gettime = ::clock_gettime; | |
971 } | |
972 } | |
973 #endif | |
974 | |
975 | |
976 jlong os::javaTimeNanos() { | |
977 if (Bsd::supports_monotonic_clock()) { | |
978 struct timespec tp; | |
979 int status = Bsd::clock_gettime(CLOCK_MONOTONIC, &tp); | |
980 assert(status == 0, "gettime error"); | |
981 jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec); | |
982 return result; | |
983 } else { | |
984 timeval time; | |
985 int status = gettimeofday(&time, NULL); | |
986 assert(status != -1, "bsd error"); | |
987 jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec); | |
988 return 1000 * usecs; | |
989 } | |
990 } | |
991 | |
992 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { | |
993 if (Bsd::supports_monotonic_clock()) { | |
994 info_ptr->max_value = ALL_64_BITS; | |
995 | |
996 // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past | |
997 info_ptr->may_skip_backward = false; // not subject to resetting or drifting | |
998 info_ptr->may_skip_forward = false; // not subject to resetting or drifting | |
999 } else { | |
1000 // gettimeofday - based on time in seconds since the Epoch thus does not wrap | |
1001 info_ptr->max_value = ALL_64_BITS; | |
1002 | |
1003 // gettimeofday is a real time clock so it skips | |
1004 info_ptr->may_skip_backward = true; | |
1005 info_ptr->may_skip_forward = true; | |
1006 } | |
1007 | |
1008 info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time | |
1009 } | |
1010 | |
1011 // Return the real, user, and system times in seconds from an | |
1012 // arbitrary fixed point in the past. | |
1013 bool os::getTimesSecs(double* process_real_time, | |
1014 double* process_user_time, | |
1015 double* process_system_time) { | |
1016 struct tms ticks; | |
1017 clock_t real_ticks = times(&ticks); | |
1018 | |
1019 if (real_ticks == (clock_t) (-1)) { | |
1020 return false; | |
1021 } else { | |
1022 double ticks_per_second = (double) clock_tics_per_sec; | |
1023 *process_user_time = ((double) ticks.tms_utime) / ticks_per_second; | |
1024 *process_system_time = ((double) ticks.tms_stime) / ticks_per_second; | |
1025 *process_real_time = ((double) real_ticks) / ticks_per_second; | |
1026 | |
1027 return true; | |
1028 } | |
1029 } | |
1030 | |
1031 | |
1032 char * os::local_time_string(char *buf, size_t buflen) { | |
1033 struct tm t; | |
1034 time_t long_time; | |
1035 time(&long_time); | |
1036 localtime_r(&long_time, &t); | |
1037 jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d", | |
1038 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, | |
1039 t.tm_hour, t.tm_min, t.tm_sec); | |
1040 return buf; | |
1041 } | |
1042 | |
1043 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) { | |
1044 return localtime_r(clock, res); | |
1045 } | |
1046 | |
1047 //////////////////////////////////////////////////////////////////////////////// | |
1048 // runtime exit support | |
1049 | |
1050 // Note: os::shutdown() might be called very early during initialization, or | |
1051 // called from signal handler. Before adding something to os::shutdown(), make | |
1052 // sure it is async-safe and can handle partially initialized VM. | |
1053 void os::shutdown() { | |
1054 | |
1055 // allow PerfMemory to attempt cleanup of any persistent resources | |
1056 perfMemory_exit(); | |
1057 | |
1058 // needs to remove object in file system | |
1059 AttachListener::abort(); | |
1060 | |
1061 // flush buffered output, finish log files | |
1062 ostream_abort(); | |
1063 | |
1064 // Check for abort hook | |
1065 abort_hook_t abort_hook = Arguments::abort_hook(); | |
1066 if (abort_hook != NULL) { | |
1067 abort_hook(); | |
1068 } | |
1069 | |
1070 } | |
1071 | |
1072 // Note: os::abort() might be called very early during initialization, or | |
1073 // called from signal handler. Before adding something to os::abort(), make | |
1074 // sure it is async-safe and can handle partially initialized VM. | |
1075 void os::abort(bool dump_core) { | |
1076 os::shutdown(); | |
1077 if (dump_core) { | |
1078 #ifndef PRODUCT | |
1079 fdStream out(defaultStream::output_fd()); | |
1080 out.print_raw("Current thread is "); | |
1081 char buf[16]; | |
1082 jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id()); | |
1083 out.print_raw_cr(buf); | |
1084 out.print_raw_cr("Dumping core ..."); | |
1085 #endif | |
1086 ::abort(); // dump core | |
1087 } | |
1088 | |
1089 ::exit(1); | |
1090 } | |
1091 | |
1092 // Die immediately, no exit hook, no abort hook, no cleanup. | |
1093 void os::die() { | |
1094 // _exit() on BsdThreads only kills current thread | |
1095 ::abort(); | |
1096 } | |
1097 | |
1098 // unused on bsd for now. | |
1099 void os::set_error_file(const char *logfile) {} | |
1100 | |
1101 | |
1102 // This method is a copy of JDK's sysGetLastErrorString | |
1103 // from src/solaris/hpi/src/system_md.c | |
1104 | |
1105 size_t os::lasterror(char *buf, size_t len) { | |
1106 | |
1107 if (errno == 0) return 0; | |
1108 | |
1109 const char *s = ::strerror(errno); | |
1110 size_t n = ::strlen(s); | |
1111 if (n >= len) { | |
1112 n = len - 1; | |
1113 } | |
1114 ::strncpy(buf, s, n); | |
1115 buf[n] = '\0'; | |
1116 return n; | |
1117 } | |
1118 | |
4961
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
1119 intx os::current_thread_id() { |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
1120 #ifdef __APPLE__ |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
1121 return (intx)::mach_thread_self(); |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
1122 #else |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
1123 return (intx)::pthread_self(); |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
1124 #endif |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
1125 } |
3960 | 1126 int os::current_process_id() { |
1127 | |
1128 // Under the old bsd thread library, bsd gives each thread | |
1129 // its own process id. Because of this each thread will return | |
1130 // a different pid if this method were to return the result | |
1131 // of getpid(2). Bsd provides no api that returns the pid | |
1132 // of the launcher thread for the vm. This implementation | |
1133 // returns a unique pid, the pid of the launcher thread | |
1134 // that starts the vm 'process'. | |
1135 | |
1136 // Under the NPTL, getpid() returns the same pid as the | |
1137 // launcher thread rather than a unique pid per thread. | |
1138 // Use gettid() if you want the old pre NPTL behaviour. | |
1139 | |
1140 // if you are looking for the result of a call to getpid() that | |
1141 // returns a unique pid for the calling thread, then look at the | |
1142 // OSThread::thread_id() method in osThread_bsd.hpp file | |
1143 | |
1144 return (int)(_initial_pid ? _initial_pid : getpid()); | |
1145 } | |
1146 | |
1147 // DLL functions | |
1148 | |
1149 #define JNI_LIB_PREFIX "lib" | |
1150 #ifdef __APPLE__ | |
1151 #define JNI_LIB_SUFFIX ".dylib" | |
1152 #else | |
1153 #define JNI_LIB_SUFFIX ".so" | |
1154 #endif | |
1155 | |
1156 const char* os::dll_file_extension() { return JNI_LIB_SUFFIX; } | |
1157 | |
1158 // This must be hard coded because it's the system's temporary | |
1159 // directory not the java application's temp directory, ala java.io.tmpdir. | |
4006 | 1160 #ifdef __APPLE__ |
1161 // macosx has a secure per-user temporary directory | |
1162 char temp_path_storage[PATH_MAX]; | |
1163 const char* os::get_temp_directory() { | |
1164 static char *temp_path = NULL; | |
1165 if (temp_path == NULL) { | |
1166 int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, temp_path_storage, PATH_MAX); | |
1167 if (pathSize == 0 || pathSize > PATH_MAX) { | |
1168 strlcpy(temp_path_storage, "/tmp/", sizeof(temp_path_storage)); | |
1169 } | |
1170 temp_path = temp_path_storage; | |
1171 } | |
1172 return temp_path; | |
1173 } | |
1174 #else /* __APPLE__ */ | |
3960 | 1175 const char* os::get_temp_directory() { return "/tmp"; } |
4006 | 1176 #endif /* __APPLE__ */ |
3960 | 1177 |
1178 static bool file_exists(const char* filename) { | |
1179 struct stat statbuf; | |
1180 if (filename == NULL || strlen(filename) == 0) { | |
1181 return false; | |
1182 } | |
1183 return os::stat(filename, &statbuf) == 0; | |
1184 } | |
1185 | |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6918
diff
changeset
|
1186 bool os::dll_build_name(char* buffer, size_t buflen, |
3960 | 1187 const char* pname, const char* fname) { |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6918
diff
changeset
|
1188 bool retval = false; |
3960 | 1189 // Copied from libhpi |
1190 const size_t pnamelen = pname ? strlen(pname) : 0; | |
1191 | |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6918
diff
changeset
|
1192 // Return error on buffer overflow. |
3960 | 1193 if (pnamelen + strlen(fname) + strlen(JNI_LIB_PREFIX) + strlen(JNI_LIB_SUFFIX) + 2 > buflen) { |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6918
diff
changeset
|
1194 return retval; |
3960 | 1195 } |
1196 | |
1197 if (pnamelen == 0) { | |
1198 snprintf(buffer, buflen, JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, fname); | |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6918
diff
changeset
|
1199 retval = true; |
3960 | 1200 } else if (strchr(pname, *os::path_separator()) != NULL) { |
1201 int n; | |
1202 char** pelements = split_path(pname, &n); | |
1203 for (int i = 0 ; i < n ; i++) { | |
1204 // Really shouldn't be NULL, but check can't hurt | |
1205 if (pelements[i] == NULL || strlen(pelements[i]) == 0) { | |
1206 continue; // skip the empty path values | |
1207 } | |
1208 snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, | |
1209 pelements[i], fname); | |
1210 if (file_exists(buffer)) { | |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6918
diff
changeset
|
1211 retval = true; |
3960 | 1212 break; |
1213 } | |
1214 } | |
1215 // release the storage | |
1216 for (int i = 0 ; i < n ; i++) { | |
1217 if (pelements[i] != NULL) { | |
6197 | 1218 FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal); |
3960 | 1219 } |
1220 } | |
1221 if (pelements != NULL) { | |
6197 | 1222 FREE_C_HEAP_ARRAY(char*, pelements, mtInternal); |
3960 | 1223 } |
1224 } else { | |
1225 snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname); | |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6918
diff
changeset
|
1226 retval = true; |
3960 | 1227 } |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6918
diff
changeset
|
1228 return retval; |
3960 | 1229 } |
1230 | |
1231 const char* os::get_current_directory(char *buf, int buflen) { | |
1232 return getcwd(buf, buflen); | |
1233 } | |
1234 | |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
1235 // check if addr is inside libjvm.so |
3960 | 1236 bool os::address_is_in_vm(address addr) { |
1237 static address libjvm_base_addr; | |
1238 Dl_info dlinfo; | |
1239 | |
1240 if (libjvm_base_addr == NULL) { | |
1241 dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo); | |
1242 libjvm_base_addr = (address)dlinfo.dli_fbase; | |
1243 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); | |
1244 } | |
1245 | |
1246 if (dladdr((void *)addr, &dlinfo)) { | |
1247 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; | |
1248 } | |
1249 | |
1250 return false; | |
1251 } | |
1252 | |
6258 | 1253 |
1254 #define MACH_MAXSYMLEN 256 | |
1255 | |
3960 | 1256 bool os::dll_address_to_function_name(address addr, char *buf, |
1257 int buflen, int *offset) { | |
1258 Dl_info dlinfo; | |
6258 | 1259 char localbuf[MACH_MAXSYMLEN]; |
1260 | |
1261 // dladdr will find names of dynamic functions only, but does | |
1262 // it set dli_fbase with mach_header address when it "fails" ? | |
3960 | 1263 if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) { |
1264 if (buf != NULL) { | |
1265 if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { | |
1266 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); | |
1267 } | |
1268 } | |
1269 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; | |
1270 return true; | |
1271 } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) { | |
1272 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), | |
4805
db18ca98d237
7131050: fix for "7071311 Decoder enhancement" does not build on MacOS X
zgu
parents:
4734
diff
changeset
|
1273 buf, buflen, offset, dlinfo.dli_fname)) { |
3960 | 1274 return true; |
1275 } | |
1276 } | |
1277 | |
6258 | 1278 // Handle non-dymanic manually: |
1279 if (dlinfo.dli_fbase != NULL && | |
1280 Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset, dlinfo.dli_fbase)) { | |
1281 if(!Decoder::demangle(localbuf, buf, buflen)) { | |
1282 jio_snprintf(buf, buflen, "%s", localbuf); | |
1283 } | |
1284 return true; | |
1285 } | |
3960 | 1286 if (buf != NULL) buf[0] = '\0'; |
1287 if (offset != NULL) *offset = -1; | |
1288 return false; | |
1289 } | |
1290 | |
1291 // ported from solaris version | |
1292 bool os::dll_address_to_library_name(address addr, char* buf, | |
1293 int buflen, int* offset) { | |
1294 Dl_info dlinfo; | |
1295 | |
1296 if (dladdr((void*)addr, &dlinfo)){ | |
1297 if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); | |
1298 if (offset) *offset = addr - (address)dlinfo.dli_fbase; | |
1299 return true; | |
1300 } else { | |
1301 if (buf) buf[0] = '\0'; | |
1302 if (offset) *offset = -1; | |
1303 return false; | |
1304 } | |
1305 } | |
6918 | 1306 |
1307 // Loads .dll/.so and | |
1308 // in case of error it checks if .dll/.so was built for the | |
1309 // same architecture as Hotspot is running on | |
3960 | 1310 |
1311 #ifdef __APPLE__ | |
1312 void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { | |
1313 void * result= ::dlopen(filename, RTLD_LAZY); | |
1314 if (result != NULL) { | |
1315 // Successful loading | |
1316 return result; | |
1317 } | |
1318 | |
1319 // Read system error message into ebuf | |
1320 ::strncpy(ebuf, ::dlerror(), ebuflen-1); | |
1321 ebuf[ebuflen-1]='\0'; | |
1322 | |
1323 return NULL; | |
1324 } | |
1325 #else | |
1326 void * os::dll_load(const char *filename, char *ebuf, int ebuflen) | |
1327 { | |
1328 void * result= ::dlopen(filename, RTLD_LAZY); | |
1329 if (result != NULL) { | |
1330 // Successful loading | |
1331 return result; | |
1332 } | |
1333 | |
1334 Elf32_Ehdr elf_head; | |
1335 | |
1336 // Read system error message into ebuf | |
1337 // It may or may not be overwritten below | |
1338 ::strncpy(ebuf, ::dlerror(), ebuflen-1); | |
1339 ebuf[ebuflen-1]='\0'; | |
1340 int diag_msg_max_length=ebuflen-strlen(ebuf); | |
1341 char* diag_msg_buf=ebuf+strlen(ebuf); | |
1342 | |
1343 if (diag_msg_max_length==0) { | |
1344 // No more space in ebuf for additional diagnostics message | |
1345 return NULL; | |
1346 } | |
1347 | |
1348 | |
1349 int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK); | |
1350 | |
1351 if (file_descriptor < 0) { | |
1352 // Can't open library, report dlerror() message | |
1353 return NULL; | |
1354 } | |
1355 | |
1356 bool failed_to_read_elf_head= | |
1357 (sizeof(elf_head)!= | |
1358 (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ; | |
1359 | |
1360 ::close(file_descriptor); | |
1361 if (failed_to_read_elf_head) { | |
1362 // file i/o error - report dlerror() msg | |
1363 return NULL; | |
1364 } | |
1365 | |
1366 typedef struct { | |
1367 Elf32_Half code; // Actual value as defined in elf.h | |
1368 Elf32_Half compat_class; // Compatibility of archs at VM's sense | |
1369 char elf_class; // 32 or 64 bit | |
1370 char endianess; // MSB or LSB | |
1371 char* name; // String representation | |
1372 } arch_t; | |
1373 | |
1374 #ifndef EM_486 | |
1375 #define EM_486 6 /* Intel 80486 */ | |
1376 #endif | |
1377 | |
1378 #ifndef EM_MIPS_RS3_LE | |
1379 #define EM_MIPS_RS3_LE 10 /* MIPS */ | |
1380 #endif | |
1381 | |
1382 #ifndef EM_PPC64 | |
1383 #define EM_PPC64 21 /* PowerPC64 */ | |
1384 #endif | |
1385 | |
1386 #ifndef EM_S390 | |
1387 #define EM_S390 22 /* IBM System/390 */ | |
1388 #endif | |
1389 | |
1390 #ifndef EM_IA_64 | |
1391 #define EM_IA_64 50 /* HP/Intel IA-64 */ | |
1392 #endif | |
1393 | |
1394 #ifndef EM_X86_64 | |
1395 #define EM_X86_64 62 /* AMD x86-64 */ | |
1396 #endif | |
1397 | |
1398 static const arch_t arch_array[]={ | |
1399 {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, | |
1400 {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, | |
1401 {EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"}, | |
1402 {EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"}, | |
1403 {EM_SPARC, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, | |
1404 {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, | |
1405 {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"}, | |
1406 {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"}, | |
1407 {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}, | |
1408 {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"}, | |
1409 {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"}, | |
1410 {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"}, | |
1411 {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"}, | |
1412 {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"}, | |
1413 {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"}, | |
1414 {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"} | |
1415 }; | |
1416 | |
1417 #if (defined IA32) | |
1418 static Elf32_Half running_arch_code=EM_386; | |
1419 #elif (defined AMD64) | |
1420 static Elf32_Half running_arch_code=EM_X86_64; | |
1421 #elif (defined IA64) | |
1422 static Elf32_Half running_arch_code=EM_IA_64; | |
1423 #elif (defined __sparc) && (defined _LP64) | |
1424 static Elf32_Half running_arch_code=EM_SPARCV9; | |
1425 #elif (defined __sparc) && (!defined _LP64) | |
1426 static Elf32_Half running_arch_code=EM_SPARC; | |
1427 #elif (defined __powerpc64__) | |
1428 static Elf32_Half running_arch_code=EM_PPC64; | |
1429 #elif (defined __powerpc__) | |
1430 static Elf32_Half running_arch_code=EM_PPC; | |
1431 #elif (defined ARM) | |
1432 static Elf32_Half running_arch_code=EM_ARM; | |
1433 #elif (defined S390) | |
1434 static Elf32_Half running_arch_code=EM_S390; | |
1435 #elif (defined ALPHA) | |
1436 static Elf32_Half running_arch_code=EM_ALPHA; | |
1437 #elif (defined MIPSEL) | |
1438 static Elf32_Half running_arch_code=EM_MIPS_RS3_LE; | |
1439 #elif (defined PARISC) | |
1440 static Elf32_Half running_arch_code=EM_PARISC; | |
1441 #elif (defined MIPS) | |
1442 static Elf32_Half running_arch_code=EM_MIPS; | |
1443 #elif (defined M68K) | |
1444 static Elf32_Half running_arch_code=EM_68K; | |
1445 #else | |
1446 #error Method os::dll_load requires that one of following is defined:\ | |
1447 IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K | |
1448 #endif | |
1449 | |
1450 // Identify compatability class for VM's architecture and library's architecture | |
1451 // Obtain string descriptions for architectures | |
1452 | |
1453 arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL}; | |
1454 int running_arch_index=-1; | |
1455 | |
1456 for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) { | |
1457 if (running_arch_code == arch_array[i].code) { | |
1458 running_arch_index = i; | |
1459 } | |
1460 if (lib_arch.code == arch_array[i].code) { | |
1461 lib_arch.compat_class = arch_array[i].compat_class; | |
1462 lib_arch.name = arch_array[i].name; | |
1463 } | |
1464 } | |
1465 | |
1466 assert(running_arch_index != -1, | |
1467 "Didn't find running architecture code (running_arch_code) in arch_array"); | |
1468 if (running_arch_index == -1) { | |
1469 // Even though running architecture detection failed | |
1470 // we may still continue with reporting dlerror() message | |
1471 return NULL; | |
1472 } | |
1473 | |
1474 if (lib_arch.endianess != arch_array[running_arch_index].endianess) { | |
1475 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)"); | |
1476 return NULL; | |
1477 } | |
1478 | |
1479 #ifndef S390 | |
1480 if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) { | |
1481 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)"); | |
1482 return NULL; | |
1483 } | |
1484 #endif // !S390 | |
1485 | |
1486 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) { | |
1487 if ( lib_arch.name!=NULL ) { | |
1488 ::snprintf(diag_msg_buf, diag_msg_max_length-1, | |
1489 " (Possible cause: can't load %s-bit .so on a %s-bit platform)", | |
1490 lib_arch.name, arch_array[running_arch_index].name); | |
1491 } else { | |
1492 ::snprintf(diag_msg_buf, diag_msg_max_length-1, | |
1493 " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)", | |
1494 lib_arch.code, | |
1495 arch_array[running_arch_index].name); | |
1496 } | |
1497 } | |
1498 | |
1499 return NULL; | |
1500 } | |
1501 #endif /* !__APPLE__ */ | |
1502 | |
1503 // XXX: Do we need a lock around this as per Linux? | |
1504 void* os::dll_lookup(void* handle, const char* name) { | |
1505 return dlsym(handle, name); | |
1506 } | |
1507 | |
1508 | |
1509 static bool _print_ascii_file(const char* filename, outputStream* st) { | |
1510 int fd = ::open(filename, O_RDONLY); | |
1511 if (fd == -1) { | |
1512 return false; | |
1513 } | |
1514 | |
1515 char buf[32]; | |
1516 int bytes; | |
1517 while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) { | |
1518 st->print_raw(buf, bytes); | |
1519 } | |
1520 | |
1521 ::close(fd); | |
1522 | |
1523 return true; | |
1524 } | |
1525 | |
1526 void os::print_dll_info(outputStream *st) { | |
1527 st->print_cr("Dynamic libraries:"); | |
1528 #ifdef RTLD_DI_LINKMAP | |
1529 Dl_info dli; | |
1530 void *handle; | |
1531 Link_map *map; | |
1532 Link_map *p; | |
1533 | |
1534 if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) { | |
1535 st->print_cr("Error: Cannot print dynamic libraries."); | |
1536 return; | |
1537 } | |
1538 handle = dlopen(dli.dli_fname, RTLD_LAZY); | |
1539 if (handle == NULL) { | |
1540 st->print_cr("Error: Cannot print dynamic libraries."); | |
1541 return; | |
1542 } | |
1543 dlinfo(handle, RTLD_DI_LINKMAP, &map); | |
1544 if (map == NULL) { | |
1545 st->print_cr("Error: Cannot print dynamic libraries."); | |
1546 return; | |
1547 } | |
1548 | |
1549 while (map->l_prev != NULL) | |
1550 map = map->l_prev; | |
1551 | |
1552 while (map != NULL) { | |
1553 st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); | |
1554 map = map->l_next; | |
1555 } | |
1556 | |
1557 dlclose(handle); | |
1558 #elif defined(__APPLE__) | |
1559 uint32_t count; | |
1560 uint32_t i; | |
1561 | |
1562 count = _dyld_image_count(); | |
1563 for (i = 1; i < count; i++) { | |
1564 const char *name = _dyld_get_image_name(i); | |
1565 intptr_t slide = _dyld_get_image_vmaddr_slide(i); | |
1566 st->print_cr(PTR_FORMAT " \t%s", slide, name); | |
1567 } | |
1568 #else | |
1569 st->print_cr("Error: Cannot print dynamic libraries."); | |
1570 #endif | |
1571 } | |
1572 | |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1573 void os::print_os_info_brief(outputStream* st) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1574 st->print("Bsd"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1575 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1576 os::Posix::print_uname_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1577 } |
3960 | 1578 |
1579 void os::print_os_info(outputStream* st) { | |
1580 st->print("OS:"); | |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1581 st->print("Bsd"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1582 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1583 os::Posix::print_uname_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1584 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1585 os::Posix::print_rlimit_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1586 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5921
diff
changeset
|
1587 os::Posix::print_load_average(st); |
3960 | 1588 } |
1589 | |
1590 void os::pd_print_cpu_info(outputStream* st) { | |
1591 // Nothing to do for now. | |
1592 } | |
1593 | |
1594 void os::print_memory_info(outputStream* st) { | |
1595 | |
1596 st->print("Memory:"); | |
1597 st->print(" %dk page", os::vm_page_size()>>10); | |
1598 | |
1599 st->print(", physical " UINT64_FORMAT "k", | |
1600 os::physical_memory() >> 10); | |
1601 st->print("(" UINT64_FORMAT "k free)", | |
1602 os::available_memory() >> 10); | |
1603 st->cr(); | |
1604 | |
1605 // meminfo | |
1606 st->print("\n/proc/meminfo:\n"); | |
1607 _print_ascii_file("/proc/meminfo", st); | |
1608 st->cr(); | |
1609 } | |
1610 | |
1611 // Taken from /usr/include/bits/siginfo.h Supposed to be architecture specific | |
1612 // but they're the same for all the bsd arch that we support | |
1613 // and they're the same for solaris but there's no common place to put this. | |
1614 const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR", | |
1615 "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG", | |
1616 "ILL_COPROC", "ILL_BADSTK" }; | |
1617 | |
1618 const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV", | |
1619 "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES", | |
1620 "FPE_FLTINV", "FPE_FLTSUB", "FPE_FLTDEN" }; | |
1621 | |
1622 const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" }; | |
1623 | |
1624 const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" }; | |
1625 | |
1626 void os::print_siginfo(outputStream* st, void* siginfo) { | |
1627 st->print("siginfo:"); | |
1628 | |
1629 const int buflen = 100; | |
1630 char buf[buflen]; | |
1631 siginfo_t *si = (siginfo_t*)siginfo; | |
1632 st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen)); | |
1633 if (si->si_errno != 0 && strerror_r(si->si_errno, buf, buflen) == 0) { | |
1634 st->print("si_errno=%s", buf); | |
1635 } else { | |
1636 st->print("si_errno=%d", si->si_errno); | |
1637 } | |
1638 const int c = si->si_code; | |
1639 assert(c > 0, "unexpected si_code"); | |
1640 switch (si->si_signo) { | |
1641 case SIGILL: | |
1642 st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]); | |
1643 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
1644 break; | |
1645 case SIGFPE: | |
1646 st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]); | |
1647 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
1648 break; | |
1649 case SIGSEGV: | |
1650 st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]); | |
1651 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
1652 break; | |
1653 case SIGBUS: | |
1654 st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]); | |
1655 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
1656 break; | |
1657 default: | |
1658 st->print(", si_code=%d", si->si_code); | |
1659 // no si_addr | |
1660 } | |
1661 | |
1662 if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) && | |
1663 UseSharedSpaces) { | |
1664 FileMapInfo* mapinfo = FileMapInfo::current_info(); | |
1665 if (mapinfo->is_in_shared_space(si->si_addr)) { | |
1666 st->print("\n\nError accessing class data sharing archive." \ | |
1667 " Mapped file inaccessible during execution, " \ | |
1668 " possible disk/network problem."); | |
1669 } | |
1670 } | |
1671 st->cr(); | |
1672 } | |
1673 | |
1674 | |
1675 static void print_signal_handler(outputStream* st, int sig, | |
1676 char* buf, size_t buflen); | |
1677 | |
1678 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { | |
1679 st->print_cr("Signal Handlers:"); | |
1680 print_signal_handler(st, SIGSEGV, buf, buflen); | |
1681 print_signal_handler(st, SIGBUS , buf, buflen); | |
1682 print_signal_handler(st, SIGFPE , buf, buflen); | |
1683 print_signal_handler(st, SIGPIPE, buf, buflen); | |
1684 print_signal_handler(st, SIGXFSZ, buf, buflen); | |
1685 print_signal_handler(st, SIGILL , buf, buflen); | |
1686 print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen); | |
1687 print_signal_handler(st, SR_signum, buf, buflen); | |
1688 print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen); | |
1689 print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen); | |
1690 print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen); | |
1691 print_signal_handler(st, BREAK_SIGNAL, buf, buflen); | |
1692 } | |
1693 | |
1694 static char saved_jvm_path[MAXPATHLEN] = {0}; | |
1695 | |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
1696 // Find the full path to the current module, libjvm |
3960 | 1697 void os::jvm_path(char *buf, jint buflen) { |
1698 // Error checking. | |
1699 if (buflen < MAXPATHLEN) { | |
1700 assert(false, "must use a large-enough buffer"); | |
1701 buf[0] = '\0'; | |
1702 return; | |
1703 } | |
1704 // Lazy resolve the path to current module. | |
1705 if (saved_jvm_path[0] != 0) { | |
1706 strcpy(buf, saved_jvm_path); | |
1707 return; | |
1708 } | |
1709 | |
1710 char dli_fname[MAXPATHLEN]; | |
1711 bool ret = dll_address_to_library_name( | |
1712 CAST_FROM_FN_PTR(address, os::jvm_path), | |
1713 dli_fname, sizeof(dli_fname), NULL); | |
1714 assert(ret != 0, "cannot locate libjvm"); | |
1715 char *rp = realpath(dli_fname, buf); | |
1716 if (rp == NULL) | |
1717 return; | |
1718 | |
1719 if (Arguments::created_by_gamma_launcher()) { | |
1720 // Support for the gamma launcher. Typical value for buf is | |
4846 | 1721 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm". If "/jre/lib/" appears at |
3960 | 1722 // the right place in the string, then assume we are installed in a JDK and |
4846 | 1723 // we're done. Otherwise, check for a JAVA_HOME environment variable and |
1724 // construct a path to the JVM being overridden. | |
1725 | |
3960 | 1726 const char *p = buf + strlen(buf) - 1; |
1727 for (int count = 0; p > buf && count < 5; ++count) { | |
1728 for (--p; p > buf && *p != '/'; --p) | |
1729 /* empty */ ; | |
1730 } | |
1731 | |
1732 if (strncmp(p, "/jre/lib/", 9) != 0) { | |
1733 // Look for JAVA_HOME in the environment. | |
1734 char* java_home_var = ::getenv("JAVA_HOME"); | |
1735 if (java_home_var != NULL && java_home_var[0] != 0) { | |
1736 char* jrelib_p; | |
1737 int len; | |
1738 | |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
1739 // Check the current module name "libjvm" |
3960 | 1740 p = strrchr(buf, '/'); |
1741 assert(strstr(p, "/libjvm") == p, "invalid library name"); | |
1742 | |
1743 rp = realpath(java_home_var, buf); | |
1744 if (rp == NULL) | |
1745 return; | |
1746 | |
1747 // determine if this is a legacy image or modules image | |
1748 // modules image doesn't have "jre" subdirectory | |
1749 len = strlen(buf); | |
1750 jrelib_p = buf + len; | |
4846 | 1751 |
1752 // Add the appropriate library subdir | |
1753 snprintf(jrelib_p, buflen-len, "/jre/lib"); | |
3960 | 1754 if (0 != access(buf, F_OK)) { |
4846 | 1755 snprintf(jrelib_p, buflen-len, "/lib"); |
3960 | 1756 } |
1757 | |
4846 | 1758 // Add the appropriate client or server subdir |
1759 len = strlen(buf); | |
1760 jrelib_p = buf + len; | |
1761 snprintf(jrelib_p, buflen-len, "/%s", COMPILER_VARIANT); | |
1762 if (0 != access(buf, F_OK)) { | |
1763 snprintf(jrelib_p, buflen-len, ""); | |
1764 } | |
1765 | |
1766 // If the path exists within JAVA_HOME, add the JVM library name | |
1767 // to complete the path to JVM being overridden. Otherwise fallback | |
1768 // to the path to the current library. | |
3960 | 1769 if (0 == access(buf, F_OK)) { |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
1770 // Use current module name "libjvm" |
3960 | 1771 len = strlen(buf); |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
1772 snprintf(buf + len, buflen-len, "/libjvm%s", JNI_LIB_SUFFIX); |
3960 | 1773 } else { |
4846 | 1774 // Fall back to path of current library |
3960 | 1775 rp = realpath(dli_fname, buf); |
1776 if (rp == NULL) | |
1777 return; | |
1778 } | |
1779 } | |
1780 } | |
1781 } | |
1782 | |
1783 strcpy(saved_jvm_path, buf); | |
1784 } | |
1785 | |
1786 void os::print_jni_name_prefix_on(outputStream* st, int args_size) { | |
1787 // no prefix required, not even "_" | |
1788 } | |
1789 | |
1790 void os::print_jni_name_suffix_on(outputStream* st, int args_size) { | |
1791 // no suffix required | |
1792 } | |
1793 | |
1794 //////////////////////////////////////////////////////////////////////////////// | |
1795 // sun.misc.Signal support | |
1796 | |
1797 static volatile jint sigint_count = 0; | |
1798 | |
1799 static void | |
1800 UserHandler(int sig, void *siginfo, void *context) { | |
1801 // 4511530 - sem_post is serialized and handled by the manager thread. When | |
1802 // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We | |
1803 // don't want to flood the manager thread with sem_post requests. | |
1804 if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1) | |
1805 return; | |
1806 | |
1807 // Ctrl-C is pressed during error reporting, likely because the error | |
1808 // handler fails to abort. Let VM die immediately. | |
1809 if (sig == SIGINT && is_error_reported()) { | |
1810 os::die(); | |
1811 } | |
1812 | |
1813 os::signal_notify(sig); | |
1814 } | |
1815 | |
1816 void* os::user_handler() { | |
1817 return CAST_FROM_FN_PTR(void*, UserHandler); | |
1818 } | |
1819 | |
1820 extern "C" { | |
1821 typedef void (*sa_handler_t)(int); | |
1822 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); | |
1823 } | |
1824 | |
1825 void* os::signal(int signal_number, void* handler) { | |
1826 struct sigaction sigAct, oldSigAct; | |
1827 | |
1828 sigfillset(&(sigAct.sa_mask)); | |
1829 sigAct.sa_flags = SA_RESTART|SA_SIGINFO; | |
1830 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler); | |
1831 | |
1832 if (sigaction(signal_number, &sigAct, &oldSigAct)) { | |
1833 // -1 means registration failed | |
1834 return (void *)-1; | |
1835 } | |
1836 | |
1837 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler); | |
1838 } | |
1839 | |
1840 void os::signal_raise(int signal_number) { | |
1841 ::raise(signal_number); | |
1842 } | |
1843 | |
1844 /* | |
1845 * The following code is moved from os.cpp for making this | |
1846 * code platform specific, which it is by its very nature. | |
1847 */ | |
1848 | |
1849 // Will be modified when max signal is changed to be dynamic | |
1850 int os::sigexitnum_pd() { | |
1851 return NSIG; | |
1852 } | |
1853 | |
1854 // a counter for each possible signal value | |
1855 static volatile jint pending_signals[NSIG+1] = { 0 }; | |
1856 | |
1857 // Bsd(POSIX) specific hand shaking semaphore. | |
1858 #ifdef __APPLE__ | |
1859 static semaphore_t sig_sem; | |
1860 #define SEM_INIT(sem, value) semaphore_create(mach_task_self(), &sem, SYNC_POLICY_FIFO, value) | |
1861 #define SEM_WAIT(sem) semaphore_wait(sem); | |
1862 #define SEM_POST(sem) semaphore_signal(sem); | |
1863 #else | |
1864 static sem_t sig_sem; | |
1865 #define SEM_INIT(sem, value) sem_init(&sem, 0, value) | |
1866 #define SEM_WAIT(sem) sem_wait(&sem); | |
1867 #define SEM_POST(sem) sem_post(&sem); | |
1868 #endif | |
1869 | |
1870 void os::signal_init_pd() { | |
1871 // Initialize signal structures | |
1872 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); | |
1873 | |
1874 // Initialize signal semaphore | |
1875 ::SEM_INIT(sig_sem, 0); | |
1876 } | |
1877 | |
1878 void os::signal_notify(int sig) { | |
1879 Atomic::inc(&pending_signals[sig]); | |
1880 ::SEM_POST(sig_sem); | |
1881 } | |
1882 | |
1883 static int check_pending_signals(bool wait) { | |
1884 Atomic::store(0, &sigint_count); | |
1885 for (;;) { | |
1886 for (int i = 0; i < NSIG + 1; i++) { | |
1887 jint n = pending_signals[i]; | |
1888 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { | |
1889 return i; | |
1890 } | |
1891 } | |
1892 if (!wait) { | |
1893 return -1; | |
1894 } | |
1895 JavaThread *thread = JavaThread::current(); | |
1896 ThreadBlockInVM tbivm(thread); | |
1897 | |
1898 bool threadIsSuspended; | |
1899 do { | |
1900 thread->set_suspend_equivalent(); | |
1901 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() | |
1902 ::SEM_WAIT(sig_sem); | |
1903 | |
1904 // were we externally suspended while we were waiting? | |
1905 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); | |
1906 if (threadIsSuspended) { | |
1907 // | |
1908 // The semaphore has been incremented, but while we were waiting | |
1909 // another thread suspended us. We don't want to continue running | |
1910 // while suspended because that would surprise the thread that | |
1911 // suspended us. | |
1912 // | |
1913 ::SEM_POST(sig_sem); | |
1914 | |
1915 thread->java_suspend_self(); | |
1916 } | |
1917 } while (threadIsSuspended); | |
1918 } | |
1919 } | |
1920 | |
1921 int os::signal_lookup() { | |
1922 return check_pending_signals(false); | |
1923 } | |
1924 | |
1925 int os::signal_wait() { | |
1926 return check_pending_signals(true); | |
1927 } | |
1928 | |
1929 //////////////////////////////////////////////////////////////////////////////// | |
1930 // Virtual Memory | |
1931 | |
1932 int os::vm_page_size() { | |
1933 // Seems redundant as all get out | |
1934 assert(os::Bsd::page_size() != -1, "must call os::init"); | |
1935 return os::Bsd::page_size(); | |
1936 } | |
1937 | |
1938 // Solaris allocates memory by pages. | |
1939 int os::vm_allocation_granularity() { | |
1940 assert(os::Bsd::page_size() != -1, "must call os::init"); | |
1941 return os::Bsd::page_size(); | |
1942 } | |
1943 | |
1944 // Rationale behind this function: | |
1945 // current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable | |
1946 // mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get | |
1947 // samples for JITted code. Here we create private executable mapping over the code cache | |
1948 // and then we can use standard (well, almost, as mapping can change) way to provide | |
1949 // info for the reporting script by storing timestamp and location of symbol | |
1950 void bsd_wrap_code(char* base, size_t size) { | |
1951 static volatile jint cnt = 0; | |
1952 | |
1953 if (!UseOprofile) { | |
1954 return; | |
1955 } | |
1956 | |
1957 char buf[PATH_MAX + 1]; | |
1958 int num = Atomic::add(1, &cnt); | |
1959 | |
1960 snprintf(buf, PATH_MAX + 1, "%s/hs-vm-%d-%d", | |
1961 os::get_temp_directory(), os::current_process_id(), num); | |
1962 unlink(buf); | |
1963 | |
1964 int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU); | |
1965 | |
1966 if (fd != -1) { | |
1967 off_t rv = ::lseek(fd, size-2, SEEK_SET); | |
1968 if (rv != (off_t)-1) { | |
1969 if (::write(fd, "", 1) == 1) { | |
1970 mmap(base, size, | |
1971 PROT_READ|PROT_WRITE|PROT_EXEC, | |
1972 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0); | |
1973 } | |
1974 } | |
1975 ::close(fd); | |
1976 unlink(buf); | |
1977 } | |
1978 } | |
1979 | |
1980 // NOTE: Bsd kernel does not really reserve the pages for us. | |
1981 // All it does is to check if there are enough free pages | |
1982 // left at the time of mmap(). This could be a potential | |
1983 // problem. | |
6197 | 1984 bool os::pd_commit_memory(char* addr, size_t size, bool exec) { |
3960 | 1985 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; |
1986 #ifdef __OpenBSD__ | |
1987 // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD | |
1988 return ::mprotect(addr, size, prot) == 0; | |
1989 #else | |
1990 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, | |
1991 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); | |
1992 return res != (uintptr_t) MAP_FAILED; | |
1993 #endif | |
1994 } | |
1995 | |
1996 | |
6197 | 1997 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, |
3960 | 1998 bool exec) { |
1999 return commit_memory(addr, size, exec); | |
2000 } | |
2001 | |
6197 | 2002 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { |
3960 | 2003 } |
2004 | |
6197 | 2005 void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { |
3960 | 2006 ::madvise(addr, bytes, MADV_DONTNEED); |
2007 } | |
2008 | |
2009 void os::numa_make_global(char *addr, size_t bytes) { | |
2010 } | |
2011 | |
2012 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { | |
2013 } | |
2014 | |
2015 bool os::numa_topology_changed() { return false; } | |
2016 | |
2017 size_t os::numa_get_groups_num() { | |
2018 return 1; | |
2019 } | |
2020 | |
2021 int os::numa_get_group_id() { | |
2022 return 0; | |
2023 } | |
2024 | |
2025 size_t os::numa_get_leaf_groups(int *ids, size_t size) { | |
2026 if (size > 0) { | |
2027 ids[0] = 0; | |
2028 return 1; | |
2029 } | |
2030 return 0; | |
2031 } | |
2032 | |
2033 bool os::get_page_info(char *start, page_info* info) { | |
2034 return false; | |
2035 } | |
2036 | |
2037 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { | |
2038 return end; | |
2039 } | |
2040 | |
2041 | |
6197 | 2042 bool os::pd_uncommit_memory(char* addr, size_t size) { |
3960 | 2043 #ifdef __OpenBSD__ |
2044 // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD | |
2045 return ::mprotect(addr, size, PROT_NONE) == 0; | |
2046 #else | |
2047 uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE, | |
2048 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); | |
2049 return res != (uintptr_t) MAP_FAILED; | |
2050 #endif | |
2051 } | |
2052 | |
6197 | 2053 bool os::pd_create_stack_guard_pages(char* addr, size_t size) { |
3960 | 2054 return os::commit_memory(addr, size); |
2055 } | |
2056 | |
2057 // If this is a growable mapping, remove the guard pages entirely by | |
2058 // munmap()ping them. If not, just call uncommit_memory(). | |
2059 bool os::remove_stack_guard_pages(char* addr, size_t size) { | |
2060 return os::uncommit_memory(addr, size); | |
2061 } | |
2062 | |
2063 static address _highest_vm_reserved_address = NULL; | |
2064 | |
2065 // If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory | |
2066 // at 'requested_addr'. If there are existing memory mappings at the same | |
2067 // location, however, they will be overwritten. If 'fixed' is false, | |
2068 // 'requested_addr' is only treated as a hint, the return value may or | |
2069 // may not start from the requested address. Unlike Bsd mmap(), this | |
2070 // function returns NULL to indicate failure. | |
2071 static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) { | |
2072 char * addr; | |
2073 int flags; | |
2074 | |
2075 flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS; | |
2076 if (fixed) { | |
2077 assert((uintptr_t)requested_addr % os::Bsd::page_size() == 0, "unaligned address"); | |
2078 flags |= MAP_FIXED; | |
2079 } | |
2080 | |
2081 // Map uncommitted pages PROT_READ and PROT_WRITE, change access | |
2082 // to PROT_EXEC if executable when we commit the page. | |
2083 addr = (char*)::mmap(requested_addr, bytes, PROT_READ|PROT_WRITE, | |
2084 flags, -1, 0); | |
2085 | |
2086 if (addr != MAP_FAILED) { | |
2087 // anon_mmap() should only get called during VM initialization, | |
2088 // don't need lock (actually we can skip locking even it can be called | |
2089 // from multiple threads, because _highest_vm_reserved_address is just a | |
2090 // hint about the upper limit of non-stack memory regions.) | |
2091 if ((address)addr + bytes > _highest_vm_reserved_address) { | |
2092 _highest_vm_reserved_address = (address)addr + bytes; | |
2093 } | |
2094 } | |
2095 | |
2096 return addr == MAP_FAILED ? NULL : addr; | |
2097 } | |
2098 | |
2099 // Don't update _highest_vm_reserved_address, because there might be memory | |
2100 // regions above addr + size. If so, releasing a memory region only creates | |
2101 // a hole in the address space, it doesn't help prevent heap-stack collision. | |
2102 // | |
2103 static int anon_munmap(char * addr, size_t size) { | |
2104 return ::munmap(addr, size) == 0; | |
2105 } | |
2106 | |
6197 | 2107 char* os::pd_reserve_memory(size_t bytes, char* requested_addr, |
3960 | 2108 size_t alignment_hint) { |
2109 return anon_mmap(requested_addr, bytes, (requested_addr != NULL)); | |
2110 } | |
2111 | |
6197 | 2112 bool os::pd_release_memory(char* addr, size_t size) { |
3960 | 2113 return anon_munmap(addr, size); |
2114 } | |
2115 | |
2116 static address highest_vm_reserved_address() { | |
2117 return _highest_vm_reserved_address; | |
2118 } | |
2119 | |
2120 static bool bsd_mprotect(char* addr, size_t size, int prot) { | |
2121 // Bsd wants the mprotect address argument to be page aligned. | |
2122 char* bottom = (char*)align_size_down((intptr_t)addr, os::Bsd::page_size()); | |
2123 | |
2124 // According to SUSv3, mprotect() should only be used with mappings | |
2125 // established by mmap(), and mmap() always maps whole pages. Unaligned | |
2126 // 'addr' likely indicates problem in the VM (e.g. trying to change | |
2127 // protection of malloc'ed or statically allocated memory). Check the | |
2128 // caller if you hit this assert. | |
2129 assert(addr == bottom, "sanity check"); | |
2130 | |
2131 size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Bsd::page_size()); | |
2132 return ::mprotect(bottom, size, prot) == 0; | |
2133 } | |
2134 | |
2135 // Set protections specified | |
2136 bool os::protect_memory(char* addr, size_t bytes, ProtType prot, | |
2137 bool is_committed) { | |
2138 unsigned int p = 0; | |
2139 switch (prot) { | |
2140 case MEM_PROT_NONE: p = PROT_NONE; break; | |
2141 case MEM_PROT_READ: p = PROT_READ; break; | |
2142 case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break; | |
2143 case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break; | |
2144 default: | |
2145 ShouldNotReachHere(); | |
2146 } | |
2147 // is_committed is unused. | |
2148 return bsd_mprotect(addr, bytes, p); | |
2149 } | |
2150 | |
2151 bool os::guard_memory(char* addr, size_t size) { | |
2152 return bsd_mprotect(addr, size, PROT_NONE); | |
2153 } | |
2154 | |
2155 bool os::unguard_memory(char* addr, size_t size) { | |
2156 return bsd_mprotect(addr, size, PROT_READ|PROT_WRITE); | |
2157 } | |
2158 | |
2159 bool os::Bsd::hugetlbfs_sanity_check(bool warn, size_t page_size) { | |
6918 | 2160 return false; |
3960 | 2161 } |
2162 | |
2163 /* | |
2164 * Set the coredump_filter bits to include largepages in core dump (bit 6) | |
2165 * | |
2166 * From the coredump_filter documentation: | |
2167 * | |
2168 * - (bit 0) anonymous private memory | |
2169 * - (bit 1) anonymous shared memory | |
2170 * - (bit 2) file-backed private memory | |
2171 * - (bit 3) file-backed shared memory | |
2172 * - (bit 4) ELF header pages in file-backed private memory areas (it is | |
2173 * effective only if the bit 2 is cleared) | |
2174 * - (bit 5) hugetlb private memory | |
2175 * - (bit 6) hugetlb shared memory | |
2176 */ | |
2177 static void set_coredump_filter(void) { | |
2178 FILE *f; | |
2179 long cdm; | |
2180 | |
2181 if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) { | |
2182 return; | |
2183 } | |
2184 | |
2185 if (fscanf(f, "%lx", &cdm) != 1) { | |
2186 fclose(f); | |
2187 return; | |
2188 } | |
2189 | |
2190 rewind(f); | |
2191 | |
2192 if ((cdm & LARGEPAGES_BIT) == 0) { | |
2193 cdm |= LARGEPAGES_BIT; | |
2194 fprintf(f, "%#lx", cdm); | |
2195 } | |
2196 | |
2197 fclose(f); | |
2198 } | |
2199 | |
2200 // Large page support | |
2201 | |
2202 static size_t _large_page_size = 0; | |
2203 | |
2204 void os::large_page_init() { | |
2205 } | |
2206 | |
2207 | |
2208 char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) { | |
2209 // "exec" is passed in but not used. Creating the shared image for | |
2210 // the code cache doesn't have an SHM_X executable permission to check. | |
2211 assert(UseLargePages && UseSHM, "only for SHM large pages"); | |
2212 | |
2213 key_t key = IPC_PRIVATE; | |
2214 char *addr; | |
2215 | |
2216 bool warn_on_failure = UseLargePages && | |
2217 (!FLAG_IS_DEFAULT(UseLargePages) || | |
2218 !FLAG_IS_DEFAULT(LargePageSizeInBytes) | |
2219 ); | |
2220 char msg[128]; | |
2221 | |
2222 // Create a large shared memory region to attach to based on size. | |
2223 // Currently, size is the total size of the heap | |
2224 int shmid = shmget(key, bytes, IPC_CREAT|SHM_R|SHM_W); | |
2225 if (shmid == -1) { | |
2226 // Possible reasons for shmget failure: | |
2227 // 1. shmmax is too small for Java heap. | |
2228 // > check shmmax value: cat /proc/sys/kernel/shmmax | |
2229 // > increase shmmax value: echo "0xffffffff" > /proc/sys/kernel/shmmax | |
2230 // 2. not enough large page memory. | |
2231 // > check available large pages: cat /proc/meminfo | |
2232 // > increase amount of large pages: | |
2233 // echo new_value > /proc/sys/vm/nr_hugepages | |
2234 // Note 1: different Bsd may use different name for this property, | |
2235 // e.g. on Redhat AS-3 it is "hugetlb_pool". | |
2236 // Note 2: it's possible there's enough physical memory available but | |
2237 // they are so fragmented after a long run that they can't | |
2238 // coalesce into large pages. Try to reserve large pages when | |
2239 // the system is still "fresh". | |
2240 if (warn_on_failure) { | |
2241 jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno); | |
2242 warning(msg); | |
2243 } | |
2244 return NULL; | |
2245 } | |
2246 | |
2247 // attach to the region | |
2248 addr = (char*)shmat(shmid, req_addr, 0); | |
2249 int err = errno; | |
2250 | |
2251 // Remove shmid. If shmat() is successful, the actual shared memory segment | |
2252 // will be deleted when it's detached by shmdt() or when the process | |
2253 // terminates. If shmat() is not successful this will remove the shared | |
2254 // segment immediately. | |
2255 shmctl(shmid, IPC_RMID, NULL); | |
2256 | |
2257 if ((intptr_t)addr == -1) { | |
2258 if (warn_on_failure) { | |
2259 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); | |
2260 warning(msg); | |
2261 } | |
2262 return NULL; | |
2263 } | |
2264 | |
8711
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2265 // The memory is committed |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2266 address pc = CALLER_PC; |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2267 MemTracker::record_virtual_memory_reserve((address)addr, bytes, pc); |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2268 MemTracker::record_virtual_memory_commit((address)addr, bytes, pc); |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2269 |
3960 | 2270 return addr; |
2271 } | |
2272 | |
2273 bool os::release_memory_special(char* base, size_t bytes) { | |
2274 // detaching the SHM segment will also delete it, see reserve_memory_special() | |
2275 int rslt = shmdt(base); | |
8711
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2276 if (rslt == 0) { |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2277 MemTracker::record_virtual_memory_uncommit((address)base, bytes); |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2278 MemTracker::record_virtual_memory_release((address)base, bytes); |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2279 return true; |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2280 } else { |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2281 return false; |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2282 } |
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8675
diff
changeset
|
2283 |
3960 | 2284 } |
2285 | |
2286 size_t os::large_page_size() { | |
2287 return _large_page_size; | |
2288 } | |
2289 | |
2290 // HugeTLBFS allows application to commit large page memory on demand; | |
2291 // with SysV SHM the entire memory region must be allocated as shared | |
2292 // memory. | |
2293 bool os::can_commit_large_page_memory() { | |
2294 return UseHugeTLBFS; | |
2295 } | |
2296 | |
2297 bool os::can_execute_large_page_memory() { | |
2298 return UseHugeTLBFS; | |
2299 } | |
2300 | |
2301 // Reserve memory at an arbitrary address, only if that area is | |
2302 // available (and not reserved for something else). | |
2303 | |
6197 | 2304 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) { |
3960 | 2305 const int max_tries = 10; |
2306 char* base[max_tries]; | |
2307 size_t size[max_tries]; | |
2308 const size_t gap = 0x000000; | |
2309 | |
2310 // Assert only that the size is a multiple of the page size, since | |
2311 // that's all that mmap requires, and since that's all we really know | |
2312 // about at this low abstraction level. If we need higher alignment, | |
2313 // we can either pass an alignment to this method or verify alignment | |
2314 // in one of the methods further up the call chain. See bug 5044738. | |
2315 assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block"); | |
2316 | |
2317 // Repeatedly allocate blocks until the block is allocated at the | |
2318 // right spot. Give up after max_tries. Note that reserve_memory() will | |
2319 // automatically update _highest_vm_reserved_address if the call is | |
2320 // successful. The variable tracks the highest memory address every reserved | |
2321 // by JVM. It is used to detect heap-stack collision if running with | |
2322 // fixed-stack BsdThreads. Because here we may attempt to reserve more | |
2323 // space than needed, it could confuse the collision detecting code. To | |
2324 // solve the problem, save current _highest_vm_reserved_address and | |
2325 // calculate the correct value before return. | |
2326 address old_highest = _highest_vm_reserved_address; | |
2327 | |
2328 // Bsd mmap allows caller to pass an address as hint; give it a try first, | |
2329 // if kernel honors the hint then we can return immediately. | |
2330 char * addr = anon_mmap(requested_addr, bytes, false); | |
2331 if (addr == requested_addr) { | |
2332 return requested_addr; | |
2333 } | |
2334 | |
2335 if (addr != NULL) { | |
2336 // mmap() is successful but it fails to reserve at the requested address | |
2337 anon_munmap(addr, bytes); | |
2338 } | |
2339 | |
2340 int i; | |
2341 for (i = 0; i < max_tries; ++i) { | |
2342 base[i] = reserve_memory(bytes); | |
2343 | |
2344 if (base[i] != NULL) { | |
2345 // Is this the block we wanted? | |
2346 if (base[i] == requested_addr) { | |
2347 size[i] = bytes; | |
2348 break; | |
2349 } | |
2350 | |
2351 // Does this overlap the block we wanted? Give back the overlapped | |
2352 // parts and try again. | |
2353 | |
2354 size_t top_overlap = requested_addr + (bytes + gap) - base[i]; | |
2355 if (top_overlap >= 0 && top_overlap < bytes) { | |
2356 unmap_memory(base[i], top_overlap); | |
2357 base[i] += top_overlap; | |
2358 size[i] = bytes - top_overlap; | |
2359 } else { | |
2360 size_t bottom_overlap = base[i] + bytes - requested_addr; | |
2361 if (bottom_overlap >= 0 && bottom_overlap < bytes) { | |
2362 unmap_memory(requested_addr, bottom_overlap); | |
2363 size[i] = bytes - bottom_overlap; | |
2364 } else { | |
2365 size[i] = bytes; | |
2366 } | |
2367 } | |
2368 } | |
2369 } | |
2370 | |
2371 // Give back the unused reserved pieces. | |
2372 | |
2373 for (int j = 0; j < i; ++j) { | |
2374 if (base[j] != NULL) { | |
2375 unmap_memory(base[j], size[j]); | |
2376 } | |
2377 } | |
2378 | |
2379 if (i < max_tries) { | |
2380 _highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes); | |
2381 return requested_addr; | |
2382 } else { | |
2383 _highest_vm_reserved_address = old_highest; | |
2384 return NULL; | |
2385 } | |
2386 } | |
2387 | |
2388 size_t os::read(int fd, void *buf, unsigned int nBytes) { | |
2389 RESTARTABLE_RETURN_INT(::read(fd, buf, nBytes)); | |
2390 } | |
2391 | |
2392 // TODO-FIXME: reconcile Solaris' os::sleep with the bsd variation. | |
2393 // Solaris uses poll(), bsd uses park(). | |
2394 // Poll() is likely a better choice, assuming that Thread.interrupt() | |
2395 // generates a SIGUSRx signal. Note that SIGUSR1 can interfere with | |
2396 // SIGSEGV, see 4355769. | |
2397 | |
2398 int os::sleep(Thread* thread, jlong millis, bool interruptible) { | |
2399 assert(thread == Thread::current(), "thread consistency check"); | |
2400 | |
2401 ParkEvent * const slp = thread->_SleepEvent ; | |
2402 slp->reset() ; | |
2403 OrderAccess::fence() ; | |
2404 | |
2405 if (interruptible) { | |
2406 jlong prevtime = javaTimeNanos(); | |
2407 | |
2408 for (;;) { | |
2409 if (os::is_interrupted(thread, true)) { | |
2410 return OS_INTRPT; | |
2411 } | |
2412 | |
2413 jlong newtime = javaTimeNanos(); | |
2414 | |
2415 if (newtime - prevtime < 0) { | |
2416 // time moving backwards, should only happen if no monotonic clock | |
2417 // not a guarantee() because JVM should not abort on kernel/glibc bugs | |
2418 assert(!Bsd::supports_monotonic_clock(), "time moving backwards"); | |
2419 } else { | |
4712
e7dead7e90af
7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents:
4082
diff
changeset
|
2420 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; |
3960 | 2421 } |
2422 | |
2423 if(millis <= 0) { | |
2424 return OS_OK; | |
2425 } | |
2426 | |
2427 prevtime = newtime; | |
2428 | |
2429 { | |
2430 assert(thread->is_Java_thread(), "sanity check"); | |
2431 JavaThread *jt = (JavaThread *) thread; | |
2432 ThreadBlockInVM tbivm(jt); | |
2433 OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); | |
2434 | |
2435 jt->set_suspend_equivalent(); | |
2436 // cleared by handle_special_suspend_equivalent_condition() or | |
2437 // java_suspend_self() via check_and_wait_while_suspended() | |
2438 | |
2439 slp->park(millis); | |
2440 | |
2441 // were we externally suspended while we were waiting? | |
2442 jt->check_and_wait_while_suspended(); | |
2443 } | |
2444 } | |
2445 } else { | |
2446 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); | |
2447 jlong prevtime = javaTimeNanos(); | |
2448 | |
2449 for (;;) { | |
2450 // It'd be nice to avoid the back-to-back javaTimeNanos() calls on | |
2451 // the 1st iteration ... | |
2452 jlong newtime = javaTimeNanos(); | |
2453 | |
2454 if (newtime - prevtime < 0) { | |
2455 // time moving backwards, should only happen if no monotonic clock | |
2456 // not a guarantee() because JVM should not abort on kernel/glibc bugs | |
2457 assert(!Bsd::supports_monotonic_clock(), "time moving backwards"); | |
2458 } else { | |
4712
e7dead7e90af
7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents:
4082
diff
changeset
|
2459 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; |
3960 | 2460 } |
2461 | |
2462 if(millis <= 0) break ; | |
2463 | |
2464 prevtime = newtime; | |
2465 slp->park(millis); | |
2466 } | |
2467 return OS_OK ; | |
2468 } | |
2469 } | |
2470 | |
2471 int os::naked_sleep() { | |
2472 // %% make the sleep time an integer flag. for now use 1 millisec. | |
2473 return os::sleep(Thread::current(), 1, false); | |
2474 } | |
2475 | |
2476 // Sleep forever; naked call to OS-specific sleep; use with CAUTION | |
2477 void os::infinite_sleep() { | |
2478 while (true) { // sleep forever ... | |
2479 ::sleep(100); // ... 100 seconds at a time | |
2480 } | |
2481 } | |
2482 | |
2483 // Used to convert frequent JVM_Yield() to nops | |
2484 bool os::dont_yield() { | |
2485 return DontYieldALot; | |
2486 } | |
2487 | |
2488 void os::yield() { | |
2489 sched_yield(); | |
2490 } | |
2491 | |
2492 os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;} | |
2493 | |
2494 void os::yield_all(int attempts) { | |
2495 // Yields to all threads, including threads with lower priorities | |
2496 // Threads on Bsd are all with same priority. The Solaris style | |
2497 // os::yield_all() with nanosleep(1ms) is not necessary. | |
2498 sched_yield(); | |
2499 } | |
2500 | |
2501 // Called from the tight loops to possibly influence time-sharing heuristics | |
2502 void os::loop_breaker(int attempts) { | |
2503 os::yield_all(attempts); | |
2504 } | |
2505 | |
2506 //////////////////////////////////////////////////////////////////////////////// | |
2507 // thread priority support | |
2508 | |
2509 // Note: Normal Bsd applications are run with SCHED_OTHER policy. SCHED_OTHER | |
2510 // only supports dynamic priority, static priority must be zero. For real-time | |
2511 // applications, Bsd supports SCHED_RR which allows static priority (1-99). | |
2512 // However, for large multi-threaded applications, SCHED_RR is not only slower | |
2513 // than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out | |
2514 // of 5 runs - Sep 2005). | |
2515 // | |
2516 // The following code actually changes the niceness of kernel-thread/LWP. It | |
2517 // has an assumption that setpriority() only modifies one kernel-thread/LWP, | |
2518 // not the entire user process, and user level threads are 1:1 mapped to kernel | |
2519 // threads. It has always been the case, but could change in the future. For | |
2520 // this reason, the code should not be used as default (ThreadPriorityPolicy=0). | |
2521 // It is only used when ThreadPriorityPolicy=1 and requires root privilege. | |
2522 | |
6918 | 2523 #if !defined(__APPLE__) |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2524 int os::java_to_os_priority[CriticalPriority + 1] = { |
3960 | 2525 19, // 0 Entry should never be used |
2526 | |
2527 0, // 1 MinPriority | |
2528 3, // 2 | |
2529 6, // 3 | |
2530 | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2531 10, // 4 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2532 15, // 5 NormPriority |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2533 18, // 6 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2534 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2535 21, // 7 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2536 25, // 8 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2537 28, // 9 NearMaxPriority |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2538 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2539 31, // 10 MaxPriority |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2540 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2541 31 // 11 CriticalPriority |
3960 | 2542 }; |
6918 | 2543 #else |
3960 | 2544 /* Using Mach high-level priority assignments */ |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2545 int os::java_to_os_priority[CriticalPriority + 1] = { |
3960 | 2546 0, // 0 Entry should never be used (MINPRI_USER) |
2547 | |
2548 27, // 1 MinPriority | |
2549 28, // 2 | |
2550 29, // 3 | |
2551 | |
2552 30, // 4 | |
2553 31, // 5 NormPriority (BASEPRI_DEFAULT) | |
2554 32, // 6 | |
2555 | |
2556 33, // 7 | |
2557 34, // 8 | |
2558 35, // 9 NearMaxPriority | |
2559 | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2560 36, // 10 MaxPriority |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2561 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2562 36 // 11 CriticalPriority |
3960 | 2563 }; |
2564 #endif | |
2565 | |
2566 static int prio_init() { | |
2567 if (ThreadPriorityPolicy == 1) { | |
2568 // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1 | |
2569 // if effective uid is not root. Perhaps, a more elegant way of doing | |
2570 // this is to test CAP_SYS_NICE capability, but that will require libcap.so | |
2571 if (geteuid() != 0) { | |
2572 if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) { | |
2573 warning("-XX:ThreadPriorityPolicy requires root privilege on Bsd"); | |
2574 } | |
2575 ThreadPriorityPolicy = 0; | |
2576 } | |
2577 } | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2578 if (UseCriticalJavaThreadPriority) { |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2579 os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority]; |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4846
diff
changeset
|
2580 } |
3960 | 2581 return 0; |
2582 } | |
2583 | |
2584 OSReturn os::set_native_priority(Thread* thread, int newpri) { | |
2585 if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK; | |
2586 | |
2587 #ifdef __OpenBSD__ | |
2588 // OpenBSD pthread_setprio starves low priority threads | |
2589 return OS_OK; | |
2590 #elif defined(__FreeBSD__) | |
2591 int ret = pthread_setprio(thread->osthread()->pthread_id(), newpri); | |
2592 #elif defined(__APPLE__) || defined(__NetBSD__) | |
2593 struct sched_param sp; | |
2594 int policy; | |
2595 pthread_t self = pthread_self(); | |
2596 | |
2597 if (pthread_getschedparam(self, &policy, &sp) != 0) | |
2598 return OS_ERR; | |
2599 | |
2600 sp.sched_priority = newpri; | |
2601 if (pthread_setschedparam(self, policy, &sp) != 0) | |
2602 return OS_ERR; | |
2603 | |
2604 return OS_OK; | |
2605 #else | |
2606 int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri); | |
2607 return (ret == 0) ? OS_OK : OS_ERR; | |
2608 #endif | |
2609 } | |
2610 | |
2611 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { | |
2612 if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) { | |
2613 *priority_ptr = java_to_os_priority[NormPriority]; | |
2614 return OS_OK; | |
2615 } | |
2616 | |
2617 errno = 0; | |
2618 #if defined(__OpenBSD__) || defined(__FreeBSD__) | |
2619 *priority_ptr = pthread_getprio(thread->osthread()->pthread_id()); | |
2620 #elif defined(__APPLE__) || defined(__NetBSD__) | |
2621 int policy; | |
2622 struct sched_param sp; | |
2623 | |
2624 pthread_getschedparam(pthread_self(), &policy, &sp); | |
2625 *priority_ptr = sp.sched_priority; | |
2626 #else | |
2627 *priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id()); | |
2628 #endif | |
2629 return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR); | |
2630 } | |
2631 | |
2632 // Hint to the underlying OS that a task switch would not be good. | |
2633 // Void return because it's a hint and can fail. | |
2634 void os::hint_no_preempt() {} | |
2635 | |
2636 //////////////////////////////////////////////////////////////////////////////// | |
2637 // suspend/resume support | |
2638 | |
2639 // the low-level signal-based suspend/resume support is a remnant from the | |
2640 // old VM-suspension that used to be for java-suspension, safepoints etc, | |
2641 // within hotspot. Now there is a single use-case for this: | |
2642 // - calling get_thread_pc() on the VMThread by the flat-profiler task | |
2643 // that runs in the watcher thread. | |
2644 // The remaining code is greatly simplified from the more general suspension | |
2645 // code that used to be used. | |
2646 // | |
2647 // The protocol is quite simple: | |
2648 // - suspend: | |
2649 // - sends a signal to the target thread | |
2650 // - polls the suspend state of the osthread using a yield loop | |
2651 // - target thread signal handler (SR_handler) sets suspend state | |
2652 // and blocks in sigsuspend until continued | |
2653 // - resume: | |
2654 // - sets target osthread state to continue | |
2655 // - sends signal to end the sigsuspend loop in the SR_handler | |
2656 // | |
2657 // Note that the SR_lock plays no role in this suspend/resume protocol. | |
2658 // | |
2659 | |
2660 static void resume_clear_context(OSThread *osthread) { | |
2661 osthread->set_ucontext(NULL); | |
2662 osthread->set_siginfo(NULL); | |
2663 | |
2664 // notify the suspend action is completed, we have now resumed | |
2665 osthread->sr.clear_suspended(); | |
2666 } | |
2667 | |
2668 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) { | |
2669 osthread->set_ucontext(context); | |
2670 osthread->set_siginfo(siginfo); | |
2671 } | |
2672 | |
2673 // | |
2674 // Handler function invoked when a thread's execution is suspended or | |
2675 // resumed. We have to be careful that only async-safe functions are | |
2676 // called here (Note: most pthread functions are not async safe and | |
2677 // should be avoided.) | |
2678 // | |
2679 // Note: sigwait() is a more natural fit than sigsuspend() from an | |
2680 // interface point of view, but sigwait() prevents the signal hander | |
2681 // from being run. libpthread would get very confused by not having | |
2682 // its signal handlers run and prevents sigwait()'s use with the | |
2683 // mutex granting granting signal. | |
2684 // | |
2685 // Currently only ever called on the VMThread | |
2686 // | |
2687 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { | |
2688 // Save and restore errno to avoid confusing native code with EINTR | |
2689 // after sigsuspend. | |
2690 int old_errno = errno; | |
2691 | |
2692 Thread* thread = Thread::current(); | |
2693 OSThread* osthread = thread->osthread(); | |
2694 assert(thread->is_VM_thread(), "Must be VMThread"); | |
2695 // read current suspend action | |
2696 int action = osthread->sr.suspend_action(); | |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
8067
diff
changeset
|
2697 if (action == os::Bsd::SuspendResume::SR_SUSPEND) { |
3960 | 2698 suspend_save_context(osthread, siginfo, context); |
2699 | |
2700 // Notify the suspend action is about to be completed. do_suspend() | |
2701 // waits until SR_SUSPENDED is set and then returns. We will wait | |
2702 // here for a resume signal and that completes the suspend-other | |
2703 // action. do_suspend/do_resume is always called as a pair from | |
2704 // the same thread - so there are no races | |
2705 | |
2706 // notify the caller | |
2707 osthread->sr.set_suspended(); | |
2708 | |
2709 sigset_t suspend_set; // signals for sigsuspend() | |
2710 | |
2711 // get current set of blocked signals and unblock resume signal | |
2712 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); | |
2713 sigdelset(&suspend_set, SR_signum); | |
2714 | |
2715 // wait here until we are resumed | |
2716 do { | |
2717 sigsuspend(&suspend_set); | |
2718 // ignore all returns until we get a resume signal | |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
8067
diff
changeset
|
2719 } while (osthread->sr.suspend_action() != os::Bsd::SuspendResume::SR_CONTINUE); |
3960 | 2720 |
2721 resume_clear_context(osthread); | |
2722 | |
2723 } else { | |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
8067
diff
changeset
|
2724 assert(action == os::Bsd::SuspendResume::SR_CONTINUE, "unexpected sr action"); |
3960 | 2725 // nothing special to do - just leave the handler |
2726 } | |
2727 | |
2728 errno = old_errno; | |
2729 } | |
2730 | |
2731 | |
2732 static int SR_initialize() { | |
2733 struct sigaction act; | |
2734 char *s; | |
2735 /* Get signal number to use for suspend/resume */ | |
2736 if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { | |
2737 int sig = ::strtol(s, 0, 10); | |
2738 if (sig > 0 || sig < NSIG) { | |
2739 SR_signum = sig; | |
2740 } | |
2741 } | |
2742 | |
2743 assert(SR_signum > SIGSEGV && SR_signum > SIGBUS, | |
2744 "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769"); | |
2745 | |
2746 sigemptyset(&SR_sigset); | |
2747 sigaddset(&SR_sigset, SR_signum); | |
2748 | |
2749 /* Set up signal handler for suspend/resume */ | |
2750 act.sa_flags = SA_RESTART|SA_SIGINFO; | |
2751 act.sa_handler = (void (*)(int)) SR_handler; | |
2752 | |
2753 // SR_signum is blocked by default. | |
2754 // 4528190 - We also need to block pthread restart signal (32 on all | |
2755 // supported Bsd platforms). Note that BsdThreads need to block | |
2756 // this signal for all threads to work properly. So we don't have | |
2757 // to use hard-coded signal number when setting up the mask. | |
2758 pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask); | |
2759 | |
2760 if (sigaction(SR_signum, &act, 0) == -1) { | |
2761 return -1; | |
2762 } | |
2763 | |
2764 // Save signal flag | |
2765 os::Bsd::set_our_sigflags(SR_signum, act.sa_flags); | |
2766 return 0; | |
2767 } | |
2768 | |
2769 static int SR_finalize() { | |
2770 return 0; | |
2771 } | |
2772 | |
2773 | |
2774 // returns true on success and false on error - really an error is fatal | |
2775 // but this seems the normal response to library errors | |
2776 static bool do_suspend(OSThread* osthread) { | |
2777 // mark as suspended and send signal | |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
8067
diff
changeset
|
2778 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_SUSPEND); |
3960 | 2779 int status = pthread_kill(osthread->pthread_id(), SR_signum); |
2780 assert_status(status == 0, status, "pthread_kill"); | |
2781 | |
2782 // check status and wait until notified of suspension | |
2783 if (status == 0) { | |
2784 for (int i = 0; !osthread->sr.is_suspended(); i++) { | |
2785 os::yield_all(i); | |
2786 } | |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
8067
diff
changeset
|
2787 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE); |
3960 | 2788 return true; |
2789 } | |
2790 else { | |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
8067
diff
changeset
|
2791 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE); |
3960 | 2792 return false; |
2793 } | |
2794 } | |
2795 | |
2796 static void do_resume(OSThread* osthread) { | |
2797 assert(osthread->sr.is_suspended(), "thread should be suspended"); | |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
8067
diff
changeset
|
2798 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_CONTINUE); |
3960 | 2799 |
2800 int status = pthread_kill(osthread->pthread_id(), SR_signum); | |
2801 assert_status(status == 0, status, "pthread_kill"); | |
2802 // check status and wait unit notified of resumption | |
2803 if (status == 0) { | |
2804 for (int i = 0; osthread->sr.is_suspended(); i++) { | |
2805 os::yield_all(i); | |
2806 } | |
2807 } | |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
8067
diff
changeset
|
2808 osthread->sr.set_suspend_action(os::Bsd::SuspendResume::SR_NONE); |
3960 | 2809 } |
2810 | |
2811 //////////////////////////////////////////////////////////////////////////////// | |
2812 // interrupt support | |
2813 | |
2814 void os::interrupt(Thread* thread) { | |
2815 assert(Thread::current() == thread || Threads_lock->owned_by_self(), | |
2816 "possibility of dangling Thread pointer"); | |
2817 | |
2818 OSThread* osthread = thread->osthread(); | |
2819 | |
2820 if (!osthread->interrupted()) { | |
2821 osthread->set_interrupted(true); | |
2822 // More than one thread can get here with the same value of osthread, | |
2823 // resulting in multiple notifications. We do, however, want the store | |
2824 // to interrupted() to be visible to other threads before we execute unpark(). | |
2825 OrderAccess::fence(); | |
2826 ParkEvent * const slp = thread->_SleepEvent ; | |
2827 if (slp != NULL) slp->unpark() ; | |
2828 } | |
2829 | |
2830 // For JSR166. Unpark even if interrupt status already was set | |
2831 if (thread->is_Java_thread()) | |
2832 ((JavaThread*)thread)->parker()->unpark(); | |
2833 | |
2834 ParkEvent * ev = thread->_ParkEvent ; | |
2835 if (ev != NULL) ev->unpark() ; | |
2836 | |
2837 } | |
2838 | |
2839 bool os::is_interrupted(Thread* thread, bool clear_interrupted) { | |
2840 assert(Thread::current() == thread || Threads_lock->owned_by_self(), | |
2841 "possibility of dangling Thread pointer"); | |
2842 | |
2843 OSThread* osthread = thread->osthread(); | |
2844 | |
2845 bool interrupted = osthread->interrupted(); | |
2846 | |
2847 if (interrupted && clear_interrupted) { | |
2848 osthread->set_interrupted(false); | |
2849 // consider thread->_SleepEvent->reset() ... optional optimization | |
2850 } | |
2851 | |
2852 return interrupted; | |
2853 } | |
2854 | |
2855 /////////////////////////////////////////////////////////////////////////////////// | |
2856 // signal handling (except suspend/resume) | |
2857 | |
2858 // This routine may be used by user applications as a "hook" to catch signals. | |
2859 // The user-defined signal handler must pass unrecognized signals to this | |
2860 // routine, and if it returns true (non-zero), then the signal handler must | |
2861 // return immediately. If the flag "abort_if_unrecognized" is true, then this | |
2862 // routine will never retun false (zero), but instead will execute a VM panic | |
2863 // routine kill the process. | |
2864 // | |
2865 // If this routine returns false, it is OK to call it again. This allows | |
2866 // the user-defined signal handler to perform checks either before or after | |
2867 // the VM performs its own checks. Naturally, the user code would be making | |
2868 // a serious error if it tried to handle an exception (such as a null check | |
2869 // or breakpoint) that the VM was generating for its own correct operation. | |
2870 // | |
2871 // This routine may recognize any of the following kinds of signals: | |
2872 // SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1. | |
2873 // It should be consulted by handlers for any of those signals. | |
2874 // | |
2875 // The caller of this routine must pass in the three arguments supplied | |
2876 // to the function referred to in the "sa_sigaction" (not the "sa_handler") | |
2877 // field of the structure passed to sigaction(). This routine assumes that | |
2878 // the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART. | |
2879 // | |
2880 // Note that the VM will print warnings if it detects conflicting signal | |
2881 // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers". | |
2882 // | |
2883 extern "C" JNIEXPORT int | |
2884 JVM_handle_bsd_signal(int signo, siginfo_t* siginfo, | |
2885 void* ucontext, int abort_if_unrecognized); | |
2886 | |
2887 void signalHandler(int sig, siginfo_t* info, void* uc) { | |
2888 assert(info != NULL && uc != NULL, "it must be old kernel"); | |
8067 | 2889 int orig_errno = errno; // Preserve errno value over signal handler. |
3960 | 2890 JVM_handle_bsd_signal(sig, info, uc, true); |
8067 | 2891 errno = orig_errno; |
3960 | 2892 } |
2893 | |
2894 | |
2895 // This boolean allows users to forward their own non-matching signals | |
2896 // to JVM_handle_bsd_signal, harmlessly. | |
2897 bool os::Bsd::signal_handlers_are_installed = false; | |
2898 | |
2899 // For signal-chaining | |
2900 struct sigaction os::Bsd::sigact[MAXSIGNUM]; | |
2901 unsigned int os::Bsd::sigs = 0; | |
2902 bool os::Bsd::libjsig_is_loaded = false; | |
2903 typedef struct sigaction *(*get_signal_t)(int); | |
2904 get_signal_t os::Bsd::get_signal_action = NULL; | |
2905 | |
2906 struct sigaction* os::Bsd::get_chained_signal_action(int sig) { | |
2907 struct sigaction *actp = NULL; | |
2908 | |
2909 if (libjsig_is_loaded) { | |
2910 // Retrieve the old signal handler from libjsig | |
2911 actp = (*get_signal_action)(sig); | |
2912 } | |
2913 if (actp == NULL) { | |
2914 // Retrieve the preinstalled signal handler from jvm | |
2915 actp = get_preinstalled_handler(sig); | |
2916 } | |
2917 | |
2918 return actp; | |
2919 } | |
2920 | |
2921 static bool call_chained_handler(struct sigaction *actp, int sig, | |
2922 siginfo_t *siginfo, void *context) { | |
2923 // Call the old signal handler | |
2924 if (actp->sa_handler == SIG_DFL) { | |
2925 // It's more reasonable to let jvm treat it as an unexpected exception | |
2926 // instead of taking the default action. | |
2927 return false; | |
2928 } else if (actp->sa_handler != SIG_IGN) { | |
2929 if ((actp->sa_flags & SA_NODEFER) == 0) { | |
2930 // automaticlly block the signal | |
2931 sigaddset(&(actp->sa_mask), sig); | |
2932 } | |
2933 | |
2934 sa_handler_t hand; | |
2935 sa_sigaction_t sa; | |
2936 bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0; | |
2937 // retrieve the chained handler | |
2938 if (siginfo_flag_set) { | |
2939 sa = actp->sa_sigaction; | |
2940 } else { | |
2941 hand = actp->sa_handler; | |
2942 } | |
2943 | |
2944 if ((actp->sa_flags & SA_RESETHAND) != 0) { | |
2945 actp->sa_handler = SIG_DFL; | |
2946 } | |
2947 | |
2948 // try to honor the signal mask | |
2949 sigset_t oset; | |
2950 pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset); | |
2951 | |
2952 // call into the chained handler | |
2953 if (siginfo_flag_set) { | |
2954 (*sa)(sig, siginfo, context); | |
2955 } else { | |
2956 (*hand)(sig); | |
2957 } | |
2958 | |
2959 // restore the signal mask | |
2960 pthread_sigmask(SIG_SETMASK, &oset, 0); | |
2961 } | |
2962 // Tell jvm's signal handler the signal is taken care of. | |
2963 return true; | |
2964 } | |
2965 | |
2966 bool os::Bsd::chained_handler(int sig, siginfo_t* siginfo, void* context) { | |
2967 bool chained = false; | |
2968 // signal-chaining | |
2969 if (UseSignalChaining) { | |
2970 struct sigaction *actp = get_chained_signal_action(sig); | |
2971 if (actp != NULL) { | |
2972 chained = call_chained_handler(actp, sig, siginfo, context); | |
2973 } | |
2974 } | |
2975 return chained; | |
2976 } | |
2977 | |
2978 struct sigaction* os::Bsd::get_preinstalled_handler(int sig) { | |
2979 if ((( (unsigned int)1 << sig ) & sigs) != 0) { | |
2980 return &sigact[sig]; | |
2981 } | |
2982 return NULL; | |
2983 } | |
2984 | |
2985 void os::Bsd::save_preinstalled_handler(int sig, struct sigaction& oldAct) { | |
2986 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
2987 sigact[sig] = oldAct; | |
2988 sigs |= (unsigned int)1 << sig; | |
2989 } | |
2990 | |
2991 // for diagnostic | |
2992 int os::Bsd::sigflags[MAXSIGNUM]; | |
2993 | |
2994 int os::Bsd::get_our_sigflags(int sig) { | |
2995 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
2996 return sigflags[sig]; | |
2997 } | |
2998 | |
2999 void os::Bsd::set_our_sigflags(int sig, int flags) { | |
3000 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
3001 sigflags[sig] = flags; | |
3002 } | |
3003 | |
3004 void os::Bsd::set_signal_handler(int sig, bool set_installed) { | |
3005 // Check for overwrite. | |
3006 struct sigaction oldAct; | |
3007 sigaction(sig, (struct sigaction*)NULL, &oldAct); | |
3008 | |
3009 void* oldhand = oldAct.sa_sigaction | |
3010 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) | |
3011 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); | |
3012 if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) && | |
3013 oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) && | |
3014 oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) { | |
3015 if (AllowUserSignalHandlers || !set_installed) { | |
3016 // Do not overwrite; user takes responsibility to forward to us. | |
3017 return; | |
3018 } else if (UseSignalChaining) { | |
3019 // save the old handler in jvm | |
3020 save_preinstalled_handler(sig, oldAct); | |
3021 // libjsig also interposes the sigaction() call below and saves the | |
3022 // old sigaction on it own. | |
3023 } else { | |
3024 fatal(err_msg("Encountered unexpected pre-existing sigaction handler " | |
3025 "%#lx for signal %d.", (long)oldhand, sig)); | |
3026 } | |
3027 } | |
3028 | |
3029 struct sigaction sigAct; | |
3030 sigfillset(&(sigAct.sa_mask)); | |
3031 sigAct.sa_handler = SIG_DFL; | |
3032 if (!set_installed) { | |
3033 sigAct.sa_flags = SA_SIGINFO|SA_RESTART; | |
3034 } else { | |
3035 sigAct.sa_sigaction = signalHandler; | |
3036 sigAct.sa_flags = SA_SIGINFO|SA_RESTART; | |
3037 } | |
3038 // Save flags, which are set by ours | |
3039 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
3040 sigflags[sig] = sigAct.sa_flags; | |
3041 | |
3042 int ret = sigaction(sig, &sigAct, &oldAct); | |
3043 assert(ret == 0, "check"); | |
3044 | |
3045 void* oldhand2 = oldAct.sa_sigaction | |
3046 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) | |
3047 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); | |
3048 assert(oldhand2 == oldhand, "no concurrent signal handler installation"); | |
3049 } | |
3050 | |
3051 // install signal handlers for signals that HotSpot needs to | |
3052 // handle in order to support Java-level exception handling. | |
3053 | |
3054 void os::Bsd::install_signal_handlers() { | |
3055 if (!signal_handlers_are_installed) { | |
3056 signal_handlers_are_installed = true; | |
3057 | |
3058 // signal-chaining | |
3059 typedef void (*signal_setting_t)(); | |
3060 signal_setting_t begin_signal_setting = NULL; | |
3061 signal_setting_t end_signal_setting = NULL; | |
3062 begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t, | |
3063 dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting")); | |
3064 if (begin_signal_setting != NULL) { | |
3065 end_signal_setting = CAST_TO_FN_PTR(signal_setting_t, | |
3066 dlsym(RTLD_DEFAULT, "JVM_end_signal_setting")); | |
3067 get_signal_action = CAST_TO_FN_PTR(get_signal_t, | |
3068 dlsym(RTLD_DEFAULT, "JVM_get_signal_action")); | |
3069 libjsig_is_loaded = true; | |
3070 assert(UseSignalChaining, "should enable signal-chaining"); | |
3071 } | |
3072 if (libjsig_is_loaded) { | |
3073 // Tell libjsig jvm is setting signal handlers | |
3074 (*begin_signal_setting)(); | |
3075 } | |
3076 | |
3077 set_signal_handler(SIGSEGV, true); | |
3078 set_signal_handler(SIGPIPE, true); | |
3079 set_signal_handler(SIGBUS, true); | |
3080 set_signal_handler(SIGILL, true); | |
3081 set_signal_handler(SIGFPE, true); | |
3082 set_signal_handler(SIGXFSZ, true); | |
3083 | |
3084 #if defined(__APPLE__) | |
3085 // In Mac OS X 10.4, CrashReporter will write a crash log for all 'fatal' signals, including | |
3086 // signals caught and handled by the JVM. To work around this, we reset the mach task | |
3087 // signal handler that's placed on our process by CrashReporter. This disables | |
3088 // CrashReporter-based reporting. | |
3089 // | |
3090 // This work-around is not necessary for 10.5+, as CrashReporter no longer intercedes | |
3091 // on caught fatal signals. | |
3092 // | |
3093 // Additionally, gdb installs both standard BSD signal handlers, and mach exception | |
3094 // handlers. By replacing the existing task exception handler, we disable gdb's mach | |
3095 // exception handling, while leaving the standard BSD signal handlers functional. | |
3096 kern_return_t kr; | |
3097 kr = task_set_exception_ports(mach_task_self(), | |
3098 EXC_MASK_BAD_ACCESS | EXC_MASK_ARITHMETIC, | |
3099 MACH_PORT_NULL, | |
3100 EXCEPTION_STATE_IDENTITY, | |
3101 MACHINE_THREAD_STATE); | |
3102 | |
3103 assert(kr == KERN_SUCCESS, "could not set mach task signal handler"); | |
3104 #endif | |
3105 | |
3106 if (libjsig_is_loaded) { | |
3107 // Tell libjsig jvm finishes setting signal handlers | |
3108 (*end_signal_setting)(); | |
3109 } | |
3110 | |
3111 // We don't activate signal checker if libjsig is in place, we trust ourselves | |
3112 // and if UserSignalHandler is installed all bets are off | |
3113 if (CheckJNICalls) { | |
3114 if (libjsig_is_loaded) { | |
3115 tty->print_cr("Info: libjsig is activated, all active signal checking is disabled"); | |
3116 check_signals = false; | |
3117 } | |
3118 if (AllowUserSignalHandlers) { | |
3119 tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled"); | |
3120 check_signals = false; | |
3121 } | |
3122 } | |
3123 } | |
3124 } | |
3125 | |
3126 | |
3127 ///// | |
3128 // glibc on Bsd platform uses non-documented flag | |
3129 // to indicate, that some special sort of signal | |
3130 // trampoline is used. | |
3131 // We will never set this flag, and we should | |
3132 // ignore this flag in our diagnostic | |
3133 #ifdef SIGNIFICANT_SIGNAL_MASK | |
3134 #undef SIGNIFICANT_SIGNAL_MASK | |
3135 #endif | |
3136 #define SIGNIFICANT_SIGNAL_MASK (~0x04000000) | |
3137 | |
3138 static const char* get_signal_handler_name(address handler, | |
3139 char* buf, int buflen) { | |
3140 int offset; | |
3141 bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset); | |
3142 if (found) { | |
3143 // skip directory names | |
3144 const char *p1, *p2; | |
3145 p1 = buf; | |
3146 size_t len = strlen(os::file_separator()); | |
3147 while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len; | |
3148 jio_snprintf(buf, buflen, "%s+0x%x", p1, offset); | |
3149 } else { | |
3150 jio_snprintf(buf, buflen, PTR_FORMAT, handler); | |
3151 } | |
3152 return buf; | |
3153 } | |
3154 | |
3155 static void print_signal_handler(outputStream* st, int sig, | |
3156 char* buf, size_t buflen) { | |
3157 struct sigaction sa; | |
3158 | |
3159 sigaction(sig, NULL, &sa); | |
3160 | |
3161 // See comment for SIGNIFICANT_SIGNAL_MASK define | |
3162 sa.sa_flags &= SIGNIFICANT_SIGNAL_MASK; | |
3163 | |
3164 st->print("%s: ", os::exception_name(sig, buf, buflen)); | |
3165 | |
3166 address handler = (sa.sa_flags & SA_SIGINFO) | |
3167 ? CAST_FROM_FN_PTR(address, sa.sa_sigaction) | |
3168 : CAST_FROM_FN_PTR(address, sa.sa_handler); | |
3169 | |
3170 if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) { | |
3171 st->print("SIG_DFL"); | |
3172 } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) { | |
3173 st->print("SIG_IGN"); | |
3174 } else { | |
3175 st->print("[%s]", get_signal_handler_name(handler, buf, buflen)); | |
3176 } | |
3177 | |
3178 st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask); | |
3179 | |
3180 address rh = VMError::get_resetted_sighandler(sig); | |
3181 // May be, handler was resetted by VMError? | |
3182 if(rh != NULL) { | |
3183 handler = rh; | |
3184 sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK; | |
3185 } | |
3186 | |
3187 st->print(", sa_flags=" PTR32_FORMAT, sa.sa_flags); | |
3188 | |
3189 // Check: is it our handler? | |
3190 if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) || | |
3191 handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler)) { | |
3192 // It is our signal handler | |
3193 // check for flags, reset system-used one! | |
3194 if((int)sa.sa_flags != os::Bsd::get_our_sigflags(sig)) { | |
3195 st->print( | |
3196 ", flags was changed from " PTR32_FORMAT ", consider using jsig library", | |
3197 os::Bsd::get_our_sigflags(sig)); | |
3198 } | |
3199 } | |
3200 st->cr(); | |
3201 } | |
3202 | |
3203 | |
3204 #define DO_SIGNAL_CHECK(sig) \ | |
3205 if (!sigismember(&check_signal_done, sig)) \ | |
3206 os::Bsd::check_signal_handler(sig) | |
3207 | |
3208 // This method is a periodic task to check for misbehaving JNI applications | |
3209 // under CheckJNI, we can add any periodic checks here | |
3210 | |
3211 void os::run_periodic_checks() { | |
3212 | |
3213 if (check_signals == false) return; | |
3214 | |
3215 // SEGV and BUS if overridden could potentially prevent | |
3216 // generation of hs*.log in the event of a crash, debugging | |
3217 // such a case can be very challenging, so we absolutely | |
3218 // check the following for a good measure: | |
3219 DO_SIGNAL_CHECK(SIGSEGV); | |
3220 DO_SIGNAL_CHECK(SIGILL); | |
3221 DO_SIGNAL_CHECK(SIGFPE); | |
3222 DO_SIGNAL_CHECK(SIGBUS); | |
3223 DO_SIGNAL_CHECK(SIGPIPE); | |
3224 DO_SIGNAL_CHECK(SIGXFSZ); | |
3225 | |
3226 | |
3227 // ReduceSignalUsage allows the user to override these handlers | |
3228 // see comments at the very top and jvm_solaris.h | |
3229 if (!ReduceSignalUsage) { | |
3230 DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL); | |
3231 DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL); | |
3232 DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL); | |
3233 DO_SIGNAL_CHECK(BREAK_SIGNAL); | |
3234 } | |
3235 | |
3236 DO_SIGNAL_CHECK(SR_signum); | |
3237 DO_SIGNAL_CHECK(INTERRUPT_SIGNAL); | |
3238 } | |
3239 | |
3240 typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *); | |
3241 | |
3242 static os_sigaction_t os_sigaction = NULL; | |
3243 | |
3244 void os::Bsd::check_signal_handler(int sig) { | |
3245 char buf[O_BUFLEN]; | |
3246 address jvmHandler = NULL; | |
3247 | |
3248 | |
3249 struct sigaction act; | |
3250 if (os_sigaction == NULL) { | |
3251 // only trust the default sigaction, in case it has been interposed | |
3252 os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction"); | |
3253 if (os_sigaction == NULL) return; | |
3254 } | |
3255 | |
3256 os_sigaction(sig, (struct sigaction*)NULL, &act); | |
3257 | |
3258 | |
3259 act.sa_flags &= SIGNIFICANT_SIGNAL_MASK; | |
3260 | |
3261 address thisHandler = (act.sa_flags & SA_SIGINFO) | |
3262 ? CAST_FROM_FN_PTR(address, act.sa_sigaction) | |
3263 : CAST_FROM_FN_PTR(address, act.sa_handler) ; | |
3264 | |
3265 | |
3266 switch(sig) { | |
3267 case SIGSEGV: | |
3268 case SIGBUS: | |
3269 case SIGFPE: | |
3270 case SIGPIPE: | |
3271 case SIGILL: | |
3272 case SIGXFSZ: | |
3273 jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler); | |
3274 break; | |
3275 | |
3276 case SHUTDOWN1_SIGNAL: | |
3277 case SHUTDOWN2_SIGNAL: | |
3278 case SHUTDOWN3_SIGNAL: | |
3279 case BREAK_SIGNAL: | |
3280 jvmHandler = (address)user_handler(); | |
3281 break; | |
3282 | |
3283 case INTERRUPT_SIGNAL: | |
3284 jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL); | |
3285 break; | |
3286 | |
3287 default: | |
3288 if (sig == SR_signum) { | |
3289 jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler); | |
3290 } else { | |
3291 return; | |
3292 } | |
3293 break; | |
3294 } | |
3295 | |
3296 if (thisHandler != jvmHandler) { | |
3297 tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN)); | |
3298 tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN)); | |
3299 tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN)); | |
3300 // No need to check this sig any longer | |
3301 sigaddset(&check_signal_done, sig); | |
3302 } else if(os::Bsd::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Bsd::get_our_sigflags(sig)) { | |
3303 tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN)); | |
3304 tty->print("expected:" PTR32_FORMAT, os::Bsd::get_our_sigflags(sig)); | |
3305 tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags); | |
3306 // No need to check this sig any longer | |
3307 sigaddset(&check_signal_done, sig); | |
3308 } | |
3309 | |
3310 // Dump all the signal | |
3311 if (sigismember(&check_signal_done, sig)) { | |
3312 print_signal_handlers(tty, buf, O_BUFLEN); | |
3313 } | |
3314 } | |
3315 | |
3316 extern void report_error(char* file_name, int line_no, char* title, char* format, ...); | |
3317 | |
3318 extern bool signal_name(int signo, char* buf, size_t len); | |
3319 | |
3320 const char* os::exception_name(int exception_code, char* buf, size_t size) { | |
3321 if (0 < exception_code && exception_code <= SIGRTMAX) { | |
3322 // signal | |
3323 if (!signal_name(exception_code, buf, size)) { | |
3324 jio_snprintf(buf, size, "SIG%d", exception_code); | |
3325 } | |
3326 return buf; | |
3327 } else { | |
3328 return NULL; | |
3329 } | |
3330 } | |
3331 | |
3332 // this is called _before_ the most of global arguments have been parsed | |
3333 void os::init(void) { | |
3334 char dummy; /* used to get a guess on initial stack address */ | |
3335 // first_hrtime = gethrtime(); | |
3336 | |
3337 // With BsdThreads the JavaMain thread pid (primordial thread) | |
3338 // is different than the pid of the java launcher thread. | |
3339 // So, on Bsd, the launcher thread pid is passed to the VM | |
3340 // via the sun.java.launcher.pid property. | |
3341 // Use this property instead of getpid() if it was correctly passed. | |
3342 // See bug 6351349. | |
3343 pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid(); | |
3344 | |
3345 _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid(); | |
3346 | |
3347 clock_tics_per_sec = CLK_TCK; | |
3348 | |
3349 init_random(1234567); | |
3350 | |
3351 ThreadCritical::initialize(); | |
3352 | |
3353 Bsd::set_page_size(getpagesize()); | |
3354 if (Bsd::page_size() == -1) { | |
3355 fatal(err_msg("os_bsd.cpp: os::init: sysconf failed (%s)", | |
3356 strerror(errno))); | |
3357 } | |
3358 init_page_sizes((size_t) Bsd::page_size()); | |
3359 | |
3360 Bsd::initialize_system_info(); | |
3361 | |
3362 // main_thread points to the aboriginal thread | |
3363 Bsd::_main_thread = pthread_self(); | |
3364 | |
3365 Bsd::clock_init(); | |
3366 initial_time_count = os::elapsed_counter(); | |
3367 | |
3368 #ifdef __APPLE__ | |
3369 // XXXDARWIN | |
3370 // Work around the unaligned VM callbacks in hotspot's | |
3371 // sharedRuntime. The callbacks don't use SSE2 instructions, and work on | |
3372 // Linux, Solaris, and FreeBSD. On Mac OS X, dyld (rightly so) enforces | |
3373 // alignment when doing symbol lookup. To work around this, we force early | |
3374 // binding of all symbols now, thus binding when alignment is known-good. | |
3375 _dyld_bind_fully_image_containing_address((const void *) &os::init); | |
3376 #endif | |
3377 } | |
3378 | |
3379 // To install functions for atexit system call | |
3380 extern "C" { | |
3381 static void perfMemory_exit_helper() { | |
3382 perfMemory_exit(); | |
3383 } | |
3384 } | |
3385 | |
3386 // this is called _after_ the global arguments have been parsed | |
3387 jint os::init_2(void) | |
3388 { | |
3389 // Allocate a single page and mark it as readable for safepoint polling | |
3390 address polling_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | |
3391 guarantee( polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page" ); | |
3392 | |
3393 os::set_polling_page( polling_page ); | |
3394 | |
3395 #ifndef PRODUCT | |
3396 if(Verbose && PrintMiscellaneous) | |
3397 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); | |
3398 #endif | |
3399 | |
3400 if (!UseMembar) { | |
3401 address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | |
3402 guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page"); | |
3403 os::set_memory_serialize_page( mem_serialize_page ); | |
3404 | |
3405 #ifndef PRODUCT | |
3406 if(Verbose && PrintMiscellaneous) | |
3407 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); | |
3408 #endif | |
3409 } | |
3410 | |
3411 os::large_page_init(); | |
3412 | |
3413 // initialize suspend/resume support - must do this before signal_sets_init() | |
3414 if (SR_initialize() != 0) { | |
3415 perror("SR_initialize failed"); | |
3416 return JNI_ERR; | |
3417 } | |
3418 | |
3419 Bsd::signal_sets_init(); | |
3420 Bsd::install_signal_handlers(); | |
3421 | |
3422 // Check minimum allowable stack size for thread creation and to initialize | |
3423 // the java system classes, including StackOverflowError - depends on page | |
3424 // size. Add a page for compiler2 recursion in main thread. | |
3425 // Add in 2*BytesPerWord times page size to account for VM stack during | |
3426 // class initialization depending on 32 or 64 bit VM. | |
3427 os::Bsd::min_stack_allowed = MAX2(os::Bsd::min_stack_allowed, | |
3428 (size_t)(StackYellowPages+StackRedPages+StackShadowPages+ | |
3429 2*BytesPerWord COMPILER2_PRESENT(+1)) * Bsd::page_size()); | |
3430 | |
3431 size_t threadStackSizeInBytes = ThreadStackSize * K; | |
3432 if (threadStackSizeInBytes != 0 && | |
3433 threadStackSizeInBytes < os::Bsd::min_stack_allowed) { | |
3434 tty->print_cr("\nThe stack size specified is too small, " | |
3435 "Specify at least %dk", | |
3436 os::Bsd::min_stack_allowed/ K); | |
3437 return JNI_ERR; | |
3438 } | |
3439 | |
3440 // Make the stack size a multiple of the page size so that | |
3441 // the yellow/red zones can be guarded. | |
3442 JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, | |
3443 vm_page_size())); | |
3444 | |
3445 if (MaxFDLimit) { | |
3446 // set the number of file descriptors to max. print out error | |
3447 // if getrlimit/setrlimit fails but continue regardless. | |
3448 struct rlimit nbr_files; | |
3449 int status = getrlimit(RLIMIT_NOFILE, &nbr_files); | |
3450 if (status != 0) { | |
3451 if (PrintMiscellaneous && (Verbose || WizardMode)) | |
3452 perror("os::init_2 getrlimit failed"); | |
3453 } else { | |
3454 nbr_files.rlim_cur = nbr_files.rlim_max; | |
3455 | |
3456 #ifdef __APPLE__ | |
3457 // Darwin returns RLIM_INFINITY for rlim_max, but fails with EINVAL if | |
3458 // you attempt to use RLIM_INFINITY. As per setrlimit(2), OPEN_MAX must | |
3459 // be used instead | |
3460 nbr_files.rlim_cur = MIN(OPEN_MAX, nbr_files.rlim_cur); | |
3461 #endif | |
3462 | |
3463 status = setrlimit(RLIMIT_NOFILE, &nbr_files); | |
3464 if (status != 0) { | |
3465 if (PrintMiscellaneous && (Verbose || WizardMode)) | |
3466 perror("os::init_2 setrlimit failed"); | |
3467 } | |
3468 } | |
3469 } | |
3470 | |
3471 // at-exit methods are called in the reverse order of their registration. | |
3472 // atexit functions are called on return from main or as a result of a | |
3473 // call to exit(3C). There can be only 32 of these functions registered | |
3474 // and atexit() does not set errno. | |
3475 | |
3476 if (PerfAllowAtExitRegistration) { | |
3477 // only register atexit functions if PerfAllowAtExitRegistration is set. | |
3478 // atexit functions can be delayed until process exit time, which | |
3479 // can be problematic for embedded VM situations. Embedded VMs should | |
3480 // call DestroyJavaVM() to assure that VM resources are released. | |
3481 | |
3482 // note: perfMemory_exit_helper atexit function may be removed in | |
3483 // the future if the appropriate cleanup code can be added to the | |
3484 // VM_Exit VMOperation's doit method. | |
3485 if (atexit(perfMemory_exit_helper) != 0) { | |
3486 warning("os::init2 atexit(perfMemory_exit_helper) failed"); | |
3487 } | |
3488 } | |
3489 | |
3490 // initialize thread priority policy | |
3491 prio_init(); | |
3492 | |
4006 | 3493 #ifdef __APPLE__ |
3494 // dynamically link to objective c gc registration | |
3495 void *handleLibObjc = dlopen(OBJC_LIB, RTLD_LAZY); | |
3496 if (handleLibObjc != NULL) { | |
3497 objc_registerThreadWithCollectorFunction = (objc_registerThreadWithCollector_t) dlsym(handleLibObjc, OBJC_GCREGISTER); | |
3498 } | |
3499 #endif | |
3500 | |
3960 | 3501 return JNI_OK; |
3502 } | |
3503 | |
3504 // this is called at the end of vm_initialization | |
3505 void os::init_3(void) { } | |
3506 | |
3507 // Mark the polling page as unreadable | |
3508 void os::make_polling_page_unreadable(void) { | |
3509 if( !guard_memory((char*)_polling_page, Bsd::page_size()) ) | |
3510 fatal("Could not disable polling page"); | |
3511 }; | |
3512 | |
3513 // Mark the polling page as readable | |
3514 void os::make_polling_page_readable(void) { | |
3515 if( !bsd_mprotect((char *)_polling_page, Bsd::page_size(), PROT_READ)) { | |
3516 fatal("Could not enable polling page"); | |
3517 } | |
3518 }; | |
3519 | |
3520 int os::active_processor_count() { | |
3521 return _processor_count; | |
3522 } | |
3523 | |
4006 | 3524 void os::set_native_thread_name(const char *name) { |
3525 #if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5 | |
3526 // This is only supported in Snow Leopard and beyond | |
3527 if (name != NULL) { | |
3528 // Add a "Java: " prefix to the name | |
3529 char buf[MAXTHREADNAMESIZE]; | |
3530 snprintf(buf, sizeof(buf), "Java: %s", name); | |
3531 pthread_setname_np(buf); | |
3532 } | |
3533 #endif | |
3534 } | |
3535 | |
3960 | 3536 bool os::distribute_processes(uint length, uint* distribution) { |
3537 // Not yet implemented. | |
3538 return false; | |
3539 } | |
3540 | |
3541 bool os::bind_to_processor(uint processor_id) { | |
3542 // Not yet implemented. | |
3543 return false; | |
3544 } | |
3545 | |
3546 /// | |
3547 | |
3548 // Suspends the target using the signal mechanism and then grabs the PC before | |
3549 // resuming the target. Used by the flat-profiler only | |
3550 ExtendedPC os::get_thread_pc(Thread* thread) { | |
3551 // Make sure that it is called by the watcher for the VMThread | |
3552 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); | |
3553 assert(thread->is_VM_thread(), "Can only be called for VMThread"); | |
3554 | |
3555 ExtendedPC epc; | |
3556 | |
3557 OSThread* osthread = thread->osthread(); | |
3558 if (do_suspend(osthread)) { | |
3559 if (osthread->ucontext() != NULL) { | |
3560 epc = os::Bsd::ucontext_get_pc(osthread->ucontext()); | |
3561 } else { | |
3562 // NULL context is unexpected, double-check this is the VMThread | |
3563 guarantee(thread->is_VM_thread(), "can only be called for VMThread"); | |
3564 } | |
3565 do_resume(osthread); | |
3566 } | |
3567 // failure means pthread_kill failed for some reason - arguably this is | |
3568 // a fatal problem, but such problems are ignored elsewhere | |
3569 | |
3570 return epc; | |
3571 } | |
3572 | |
3573 int os::Bsd::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) | |
3574 { | |
3575 return pthread_cond_timedwait(_cond, _mutex, _abstime); | |
3576 } | |
3577 | |
3578 //////////////////////////////////////////////////////////////////////////////// | |
3579 // debug support | |
3580 | |
3581 static address same_page(address x, address y) { | |
3582 int page_bits = -os::vm_page_size(); | |
3583 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) | |
3584 return x; | |
3585 else if (x > y) | |
3586 return (address)(intptr_t(y) | ~page_bits) + 1; | |
3587 else | |
3588 return (address)(intptr_t(y) & page_bits); | |
3589 } | |
3590 | |
3591 bool os::find(address addr, outputStream* st) { | |
3592 Dl_info dlinfo; | |
3593 memset(&dlinfo, 0, sizeof(dlinfo)); | |
3594 if (dladdr(addr, &dlinfo)) { | |
3595 st->print(PTR_FORMAT ": ", addr); | |
3596 if (dlinfo.dli_sname != NULL) { | |
3597 st->print("%s+%#x", dlinfo.dli_sname, | |
3598 addr - (intptr_t)dlinfo.dli_saddr); | |
3599 } else if (dlinfo.dli_fname) { | |
3600 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); | |
3601 } else { | |
3602 st->print("<absolute address>"); | |
3603 } | |
3604 if (dlinfo.dli_fname) { | |
3605 st->print(" in %s", dlinfo.dli_fname); | |
3606 } | |
3607 if (dlinfo.dli_fbase) { | |
3608 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); | |
3609 } | |
3610 st->cr(); | |
3611 | |
3612 if (Verbose) { | |
3613 // decode some bytes around the PC | |
3614 address begin = same_page(addr-40, addr); | |
3615 address end = same_page(addr+40, addr); | |
3616 address lowest = (address) dlinfo.dli_sname; | |
3617 if (!lowest) lowest = (address) dlinfo.dli_fbase; | |
3618 if (begin < lowest) begin = lowest; | |
3619 Dl_info dlinfo2; | |
3620 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr | |
3621 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) | |
3622 end = (address) dlinfo2.dli_saddr; | |
3623 Disassembler::decode(begin, end, st); | |
3624 } | |
3625 return true; | |
3626 } | |
3627 return false; | |
3628 } | |
3629 | |
3630 //////////////////////////////////////////////////////////////////////////////// | |
3631 // misc | |
3632 | |
3633 // This does not do anything on Bsd. This is basically a hook for being | |
3634 // able to use structured exception handling (thread-local exception filters) | |
3635 // on, e.g., Win32. | |
3636 void | |
3637 os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, | |
3638 JavaCallArguments* args, Thread* thread) { | |
3639 f(value, method, args, thread); | |
3640 } | |
3641 | |
3642 void os::print_statistics() { | |
3643 } | |
3644 | |
3645 int os::message_box(const char* title, const char* message) { | |
3646 int i; | |
3647 fdStream err(defaultStream::error_fd()); | |
3648 for (i = 0; i < 78; i++) err.print_raw("="); | |
3649 err.cr(); | |
3650 err.print_raw_cr(title); | |
3651 for (i = 0; i < 78; i++) err.print_raw("-"); | |
3652 err.cr(); | |
3653 err.print_raw_cr(message); | |
3654 for (i = 0; i < 78; i++) err.print_raw("="); | |
3655 err.cr(); | |
3656 | |
3657 char buf[16]; | |
3658 // Prevent process from exiting upon "read error" without consuming all CPU | |
3659 while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); } | |
3660 | |
3661 return buf[0] == 'y' || buf[0] == 'Y'; | |
3662 } | |
3663 | |
3664 int os::stat(const char *path, struct stat *sbuf) { | |
3665 char pathbuf[MAX_PATH]; | |
3666 if (strlen(path) > MAX_PATH - 1) { | |
3667 errno = ENAMETOOLONG; | |
3668 return -1; | |
3669 } | |
3670 os::native_path(strcpy(pathbuf, path)); | |
3671 return ::stat(pathbuf, sbuf); | |
3672 } | |
3673 | |
3674 bool os::check_heap(bool force) { | |
3675 return true; | |
3676 } | |
3677 | |
3678 int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) { | |
3679 return ::vsnprintf(buf, count, format, args); | |
3680 } | |
3681 | |
3682 // Is a (classpath) directory empty? | |
3683 bool os::dir_is_empty(const char* path) { | |
3684 DIR *dir = NULL; | |
3685 struct dirent *ptr; | |
3686 | |
3687 dir = opendir(path); | |
3688 if (dir == NULL) return true; | |
3689 | |
3690 /* Scan the directory */ | |
3691 bool result = true; | |
3692 char buf[sizeof(struct dirent) + MAX_PATH]; | |
3693 while (result && (ptr = ::readdir(dir)) != NULL) { | |
3694 if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) { | |
3695 result = false; | |
3696 } | |
3697 } | |
3698 closedir(dir); | |
3699 return result; | |
3700 } | |
3701 | |
3702 // This code originates from JDK's sysOpen and open64_w | |
3703 // from src/solaris/hpi/src/system_md.c | |
3704 | |
3705 #ifndef O_DELETE | |
3706 #define O_DELETE 0x10000 | |
3707 #endif | |
3708 | |
3709 // Open a file. Unlink the file immediately after open returns | |
3710 // if the specified oflag has the O_DELETE flag set. | |
3711 // O_DELETE is used only in j2se/src/share/native/java/util/zip/ZipFile.c | |
3712 | |
3713 int os::open(const char *path, int oflag, int mode) { | |
3714 | |
3715 if (strlen(path) > MAX_PATH - 1) { | |
3716 errno = ENAMETOOLONG; | |
3717 return -1; | |
3718 } | |
3719 int fd; | |
3720 int o_delete = (oflag & O_DELETE); | |
3721 oflag = oflag & ~O_DELETE; | |
3722 | |
3723 fd = ::open(path, oflag, mode); | |
3724 if (fd == -1) return -1; | |
3725 | |
3726 //If the open succeeded, the file might still be a directory | |
3727 { | |
3728 struct stat buf; | |
3729 int ret = ::fstat(fd, &buf); | |
3730 int st_mode = buf.st_mode; | |
3731 | |
3732 if (ret != -1) { | |
3733 if ((st_mode & S_IFMT) == S_IFDIR) { | |
3734 errno = EISDIR; | |
3735 ::close(fd); | |
3736 return -1; | |
3737 } | |
3738 } else { | |
3739 ::close(fd); | |
3740 return -1; | |
3741 } | |
3742 } | |
3743 | |
3744 /* | |
3745 * All file descriptors that are opened in the JVM and not | |
3746 * specifically destined for a subprocess should have the | |
3747 * close-on-exec flag set. If we don't set it, then careless 3rd | |
3748 * party native code might fork and exec without closing all | |
3749 * appropriate file descriptors (e.g. as we do in closeDescriptors in | |
3750 * UNIXProcess.c), and this in turn might: | |
3751 * | |
3752 * - cause end-of-file to fail to be detected on some file | |
3753 * descriptors, resulting in mysterious hangs, or | |
3754 * | |
3755 * - might cause an fopen in the subprocess to fail on a system | |
3756 * suffering from bug 1085341. | |
3757 * | |
3758 * (Yes, the default setting of the close-on-exec flag is a Unix | |
3759 * design flaw) | |
3760 * | |
3761 * See: | |
3762 * 1085341: 32-bit stdio routines should support file descriptors >255 | |
3763 * 4843136: (process) pipe file descriptor from Runtime.exec not being closed | |
3764 * 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9 | |
3765 */ | |
3766 #ifdef FD_CLOEXEC | |
3767 { | |
3768 int flags = ::fcntl(fd, F_GETFD); | |
3769 if (flags != -1) | |
3770 ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC); | |
3771 } | |
3772 #endif | |
3773 | |
3774 if (o_delete != 0) { | |
3775 ::unlink(path); | |
3776 } | |
3777 return fd; | |
3778 } | |
3779 | |
3780 | |
3781 // create binary file, rewriting existing file if required | |
3782 int os::create_binary_file(const char* path, bool rewrite_existing) { | |
3783 int oflags = O_WRONLY | O_CREAT; | |
3784 if (!rewrite_existing) { | |
3785 oflags |= O_EXCL; | |
3786 } | |
3787 return ::open(path, oflags, S_IREAD | S_IWRITE); | |
3788 } | |
3789 | |
3790 // return current position of file pointer | |
3791 jlong os::current_file_offset(int fd) { | |
3792 return (jlong)::lseek(fd, (off_t)0, SEEK_CUR); | |
3793 } | |
3794 | |
3795 // move file pointer to the specified offset | |
3796 jlong os::seek_to_file_offset(int fd, jlong offset) { | |
3797 return (jlong)::lseek(fd, (off_t)offset, SEEK_SET); | |
3798 } | |
3799 | |
3800 // This code originates from JDK's sysAvailable | |
3801 // from src/solaris/hpi/src/native_threads/src/sys_api_td.c | |
3802 | |
3803 int os::available(int fd, jlong *bytes) { | |
3804 jlong cur, end; | |
3805 int mode; | |
3806 struct stat buf; | |
3807 | |
3808 if (::fstat(fd, &buf) >= 0) { | |
3809 mode = buf.st_mode; | |
3810 if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { | |
3811 /* | |
3812 * XXX: is the following call interruptible? If so, this might | |
3813 * need to go through the INTERRUPT_IO() wrapper as for other | |
3814 * blocking, interruptible calls in this file. | |
3815 */ | |
3816 int n; | |
3817 if (::ioctl(fd, FIONREAD, &n) >= 0) { | |
3818 *bytes = n; | |
3819 return 1; | |
3820 } | |
3821 } | |
3822 } | |
3823 if ((cur = ::lseek(fd, 0L, SEEK_CUR)) == -1) { | |
3824 return 0; | |
3825 } else if ((end = ::lseek(fd, 0L, SEEK_END)) == -1) { | |
3826 return 0; | |
3827 } else if (::lseek(fd, cur, SEEK_SET) == -1) { | |
3828 return 0; | |
3829 } | |
3830 *bytes = end - cur; | |
3831 return 1; | |
3832 } | |
3833 | |
3834 int os::socket_available(int fd, jint *pbytes) { | |
3835 if (fd < 0) | |
3836 return OS_OK; | |
3837 | |
3838 int ret; | |
3839 | |
3840 RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret); | |
3841 | |
3842 //%% note ioctl can return 0 when successful, JVM_SocketAvailable | |
3843 // is expected to return 0 on failure and 1 on success to the jdk. | |
3844 | |
3845 return (ret == OS_ERR) ? 0 : 1; | |
3846 } | |
3847 | |
3848 // Map a block of memory. | |
6197 | 3849 char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, |
3960 | 3850 char *addr, size_t bytes, bool read_only, |
3851 bool allow_exec) { | |
3852 int prot; | |
3853 int flags; | |
3854 | |
3855 if (read_only) { | |
3856 prot = PROT_READ; | |
3857 flags = MAP_SHARED; | |
3858 } else { | |
3859 prot = PROT_READ | PROT_WRITE; | |
3860 flags = MAP_PRIVATE; | |
3861 } | |
3862 | |
3863 if (allow_exec) { | |
3864 prot |= PROT_EXEC; | |
3865 } | |
3866 | |
3867 if (addr != NULL) { | |
3868 flags |= MAP_FIXED; | |
3869 } | |
3870 | |
3871 char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags, | |
3872 fd, file_offset); | |
3873 if (mapped_address == MAP_FAILED) { | |
3874 return NULL; | |
3875 } | |
3876 return mapped_address; | |
3877 } | |
3878 | |
3879 | |
3880 // Remap a block of memory. | |
6197 | 3881 char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, |
3960 | 3882 char *addr, size_t bytes, bool read_only, |
3883 bool allow_exec) { | |
3884 // same as map_memory() on this OS | |
3885 return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only, | |
3886 allow_exec); | |
3887 } | |
3888 | |
3889 | |
3890 // Unmap a block of memory. | |
6197 | 3891 bool os::pd_unmap_memory(char* addr, size_t bytes) { |
3960 | 3892 return munmap(addr, bytes) == 0; |
3893 } | |
3894 | |
3895 // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool) | |
3896 // are used by JVM M&M and JVMTI to get user+sys or user CPU time | |
3897 // of a thread. | |
3898 // | |
3899 // current_thread_cpu_time() and thread_cpu_time(Thread*) returns | |
3900 // the fast estimate available on the platform. | |
3901 | |
3902 jlong os::current_thread_cpu_time() { | |
3903 #ifdef __APPLE__ | |
3904 return os::thread_cpu_time(Thread::current(), true /* user + sys */); | |
8689
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3905 #else |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3906 Unimplemented(); |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3907 return 0; |
3960 | 3908 #endif |
3909 } | |
3910 | |
3911 jlong os::thread_cpu_time(Thread* thread) { | |
8689
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3912 #ifdef __APPLE__ |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3913 return os::thread_cpu_time(thread, true /* user + sys */); |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3914 #else |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3915 Unimplemented(); |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3916 return 0; |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3917 #endif |
3960 | 3918 } |
3919 | |
3920 jlong os::current_thread_cpu_time(bool user_sys_cpu_time) { | |
3921 #ifdef __APPLE__ | |
3922 return os::thread_cpu_time(Thread::current(), user_sys_cpu_time); | |
8689
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3923 #else |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3924 Unimplemented(); |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3925 return 0; |
3960 | 3926 #endif |
3927 } | |
3928 | |
3929 jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) { | |
3930 #ifdef __APPLE__ | |
3931 struct thread_basic_info tinfo; | |
3932 mach_msg_type_number_t tcount = THREAD_INFO_MAX; | |
3933 kern_return_t kr; | |
4961
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
3934 thread_t mach_thread; |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
3935 |
0368109684cb
7132070: Use a mach_port_t as the OSThread thread_id rather than pthread_t on BSD/OSX
sla
parents:
4960
diff
changeset
|
3936 mach_thread = thread->osthread()->thread_id(); |
3960 | 3937 kr = thread_info(mach_thread, THREAD_BASIC_INFO, (thread_info_t)&tinfo, &tcount); |
3938 if (kr != KERN_SUCCESS) | |
3939 return -1; | |
3940 | |
3941 if (user_sys_cpu_time) { | |
3942 jlong nanos; | |
3943 nanos = ((jlong) tinfo.system_time.seconds + tinfo.user_time.seconds) * (jlong)1000000000; | |
3944 nanos += ((jlong) tinfo.system_time.microseconds + (jlong) tinfo.user_time.microseconds) * (jlong)1000; | |
3945 return nanos; | |
3946 } else { | |
3947 return ((jlong)tinfo.user_time.seconds * 1000000000) + ((jlong)tinfo.user_time.microseconds * (jlong)1000); | |
3948 } | |
8689
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3949 #else |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3950 Unimplemented(); |
bf06968a8a00
8008559: [parfait] Path through non-void function '_ZN2os15thread_cpu_timeEP6Thread' returns an undefined value
morris
parents:
8067
diff
changeset
|
3951 return 0; |
3960 | 3952 #endif |
3953 } | |
3954 | |
3955 | |
3956 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { | |
3957 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits | |
3958 info_ptr->may_skip_backward = false; // elapsed time not wall time | |
3959 info_ptr->may_skip_forward = false; // elapsed time not wall time | |
3960 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned | |
3961 } | |
3962 | |
3963 void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { | |
3964 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits | |
3965 info_ptr->may_skip_backward = false; // elapsed time not wall time | |
3966 info_ptr->may_skip_forward = false; // elapsed time not wall time | |
3967 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned | |
3968 } | |
3969 | |
3970 bool os::is_thread_cpu_time_supported() { | |
3971 #ifdef __APPLE__ | |
3972 return true; | |
6918 | 3973 #else |
3960 | 3974 return false; |
3975 #endif | |
3976 } | |
3977 | |
3978 // System loadavg support. Returns -1 if load average cannot be obtained. | |
3979 // Bsd doesn't yet have a (official) notion of processor sets, | |
3980 // so just return the system wide load average. | |
3981 int os::loadavg(double loadavg[], int nelem) { | |
3982 return ::getloadavg(loadavg, nelem); | |
3983 } | |
3984 | |
3985 void os::pause() { | |
3986 char filename[MAX_PATH]; | |
3987 if (PauseAtStartupFile && PauseAtStartupFile[0]) { | |
3988 jio_snprintf(filename, MAX_PATH, PauseAtStartupFile); | |
3989 } else { | |
3990 jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id()); | |
3991 } | |
3992 | |
3993 int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); | |
3994 if (fd != -1) { | |
3995 struct stat buf; | |
3996 ::close(fd); | |
3997 while (::stat(filename, &buf) == 0) { | |
3998 (void)::poll(NULL, 0, 100); | |
3999 } | |
4000 } else { | |
4001 jio_fprintf(stderr, | |
4002 "Could not open pause file '%s', continuing immediately.\n", filename); | |
4003 } | |
4004 } | |
4005 | |
4006 | |
4007 // Refer to the comments in os_solaris.cpp park-unpark. | |
4008 // | |
4009 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can | |
4010 // hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable. | |
4011 // For specifics regarding the bug see GLIBC BUGID 261237 : | |
4012 // http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html. | |
4013 // Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future | |
4014 // will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar | |
4015 // is used. (The simple C test-case provided in the GLIBC bug report manifests the | |
4016 // hang). The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos() | |
4017 // and monitorenter when we're using 1-0 locking. All those operations may result in | |
4018 // calls to pthread_cond_timedwait(). Using LD_ASSUME_KERNEL to use an older version | |
4019 // of libpthread avoids the problem, but isn't practical. | |
4020 // | |
4021 // Possible remedies: | |
4022 // | |
4023 // 1. Establish a minimum relative wait time. 50 to 100 msecs seems to work. | |
4024 // This is palliative and probabilistic, however. If the thread is preempted | |
4025 // between the call to compute_abstime() and pthread_cond_timedwait(), more | |
4026 // than the minimum period may have passed, and the abstime may be stale (in the | |
4027 // past) resultin in a hang. Using this technique reduces the odds of a hang | |
4028 // but the JVM is still vulnerable, particularly on heavily loaded systems. | |
4029 // | |
4030 // 2. Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead | |
4031 // of the usual flag-condvar-mutex idiom. The write side of the pipe is set | |
4032 // NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo) | |
4033 // reduces to poll()+read(). This works well, but consumes 2 FDs per extant | |
4034 // thread. | |
4035 // | |
4036 // 3. Embargo pthread_cond_timedwait() and implement a native "chron" thread | |
4037 // that manages timeouts. We'd emulate pthread_cond_timedwait() by enqueuing | |
4038 // a timeout request to the chron thread and then blocking via pthread_cond_wait(). | |
4039 // This also works well. In fact it avoids kernel-level scalability impediments | |
4040 // on certain platforms that don't handle lots of active pthread_cond_timedwait() | |
4041 // timers in a graceful fashion. | |
4042 // | |
4043 // 4. When the abstime value is in the past it appears that control returns | |
4044 // correctly from pthread_cond_timedwait(), but the condvar is left corrupt. | |
4045 // Subsequent timedwait/wait calls may hang indefinitely. Given that, we | |
4046 // can avoid the problem by reinitializing the condvar -- by cond_destroy() | |
4047 // followed by cond_init() -- after all calls to pthread_cond_timedwait(). | |
4048 // It may be possible to avoid reinitialization by checking the return | |
4049 // value from pthread_cond_timedwait(). In addition to reinitializing the | |
4050 // condvar we must establish the invariant that cond_signal() is only called | |
4051 // within critical sections protected by the adjunct mutex. This prevents | |
4052 // cond_signal() from "seeing" a condvar that's in the midst of being | |
4053 // reinitialized or that is corrupt. Sadly, this invariant obviates the | |
4054 // desirable signal-after-unlock optimization that avoids futile context switching. | |
4055 // | |
4056 // I'm also concerned that some versions of NTPL might allocate an auxilliary | |
4057 // structure when a condvar is used or initialized. cond_destroy() would | |
4058 // release the helper structure. Our reinitialize-after-timedwait fix | |
4059 // put excessive stress on malloc/free and locks protecting the c-heap. | |
4060 // | |
4061 // We currently use (4). See the WorkAroundNTPLTimedWaitHang flag. | |
4062 // It may be possible to refine (4) by checking the kernel and NTPL verisons | |
4063 // and only enabling the work-around for vulnerable environments. | |
4064 | |
4065 // utility to compute the abstime argument to timedwait: | |
4066 // millis is the relative timeout time | |
4067 // abstime will be the absolute timeout time | |
4068 // TODO: replace compute_abstime() with unpackTime() | |
4069 | |
4070 static struct timespec* compute_abstime(struct timespec* abstime, jlong millis) { | |
4071 if (millis < 0) millis = 0; | |
4072 struct timeval now; | |
4073 int status = gettimeofday(&now, NULL); | |
4074 assert(status == 0, "gettimeofday"); | |
4075 jlong seconds = millis / 1000; | |
4076 millis %= 1000; | |
4077 if (seconds > 50000000) { // see man cond_timedwait(3T) | |
4078 seconds = 50000000; | |
4079 } | |
4080 abstime->tv_sec = now.tv_sec + seconds; | |
4081 long usec = now.tv_usec + millis * 1000; | |
4082 if (usec >= 1000000) { | |
4083 abstime->tv_sec += 1; | |
4084 usec -= 1000000; | |
4085 } | |
4086 abstime->tv_nsec = usec * 1000; | |
4087 return abstime; | |
4088 } | |
4089 | |
4090 | |
4091 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. | |
4092 // Conceptually TryPark() should be equivalent to park(0). | |
4093 | |
4094 int os::PlatformEvent::TryPark() { | |
4095 for (;;) { | |
4096 const int v = _Event ; | |
4097 guarantee ((v == 0) || (v == 1), "invariant") ; | |
4098 if (Atomic::cmpxchg (0, &_Event, v) == v) return v ; | |
4099 } | |
4100 } | |
4101 | |
4102 void os::PlatformEvent::park() { // AKA "down()" | |
4103 // Invariant: Only the thread associated with the Event/PlatformEvent | |
4104 // may call park(). | |
4105 // TODO: assert that _Assoc != NULL or _Assoc == Self | |
4106 int v ; | |
4107 for (;;) { | |
4108 v = _Event ; | |
4109 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ; | |
4110 } | |
4111 guarantee (v >= 0, "invariant") ; | |
4112 if (v == 0) { | |
4113 // Do this the hard way by blocking ... | |
4114 int status = pthread_mutex_lock(_mutex); | |
4115 assert_status(status == 0, status, "mutex_lock"); | |
4116 guarantee (_nParked == 0, "invariant") ; | |
4117 ++ _nParked ; | |
4118 while (_Event < 0) { | |
4119 status = pthread_cond_wait(_cond, _mutex); | |
4120 // for some reason, under 2.7 lwp_cond_wait() may return ETIME ... | |
4121 // Treat this the same as if the wait was interrupted | |
4122 if (status == ETIMEDOUT) { status = EINTR; } | |
4123 assert_status(status == 0 || status == EINTR, status, "cond_wait"); | |
4124 } | |
4125 -- _nParked ; | |
4126 | |
4127 _Event = 0 ; | |
4128 status = pthread_mutex_unlock(_mutex); | |
4129 assert_status(status == 0, status, "mutex_unlock"); | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4130 // Paranoia to ensure our locked and lock-free paths interact |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4131 // correctly with each other. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4132 OrderAccess::fence(); |
3960 | 4133 } |
4134 guarantee (_Event >= 0, "invariant") ; | |
4135 } | |
4136 | |
4137 int os::PlatformEvent::park(jlong millis) { | |
4138 guarantee (_nParked == 0, "invariant") ; | |
4139 | |
4140 int v ; | |
4141 for (;;) { | |
4142 v = _Event ; | |
4143 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ; | |
4144 } | |
4145 guarantee (v >= 0, "invariant") ; | |
4146 if (v != 0) return OS_OK ; | |
4147 | |
4148 // We do this the hard way, by blocking the thread. | |
4149 // Consider enforcing a minimum timeout value. | |
4150 struct timespec abst; | |
4151 compute_abstime(&abst, millis); | |
4152 | |
4153 int ret = OS_TIMEOUT; | |
4154 int status = pthread_mutex_lock(_mutex); | |
4155 assert_status(status == 0, status, "mutex_lock"); | |
4156 guarantee (_nParked == 0, "invariant") ; | |
4157 ++_nParked ; | |
4158 | |
4159 // Object.wait(timo) will return because of | |
4160 // (a) notification | |
4161 // (b) timeout | |
4162 // (c) thread.interrupt | |
4163 // | |
4164 // Thread.interrupt and object.notify{All} both call Event::set. | |
4165 // That is, we treat thread.interrupt as a special case of notification. | |
4166 // The underlying Solaris implementation, cond_timedwait, admits | |
4167 // spurious/premature wakeups, but the JLS/JVM spec prevents the | |
4168 // JVM from making those visible to Java code. As such, we must | |
4169 // filter out spurious wakeups. We assume all ETIME returns are valid. | |
4170 // | |
4171 // TODO: properly differentiate simultaneous notify+interrupt. | |
4172 // In that case, we should propagate the notify to another waiter. | |
4173 | |
4174 while (_Event < 0) { | |
4175 status = os::Bsd::safe_cond_timedwait(_cond, _mutex, &abst); | |
4176 if (status != 0 && WorkAroundNPTLTimedWaitHang) { | |
4177 pthread_cond_destroy (_cond); | |
4178 pthread_cond_init (_cond, NULL) ; | |
4179 } | |
4180 assert_status(status == 0 || status == EINTR || | |
4181 status == ETIMEDOUT, | |
4182 status, "cond_timedwait"); | |
4183 if (!FilterSpuriousWakeups) break ; // previous semantics | |
4184 if (status == ETIMEDOUT) break ; | |
4185 // We consume and ignore EINTR and spurious wakeups. | |
4186 } | |
4187 --_nParked ; | |
4188 if (_Event >= 0) { | |
4189 ret = OS_OK; | |
4190 } | |
4191 _Event = 0 ; | |
4192 status = pthread_mutex_unlock(_mutex); | |
4193 assert_status(status == 0, status, "mutex_unlock"); | |
4194 assert (_nParked == 0, "invariant") ; | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4195 // Paranoia to ensure our locked and lock-free paths interact |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4196 // correctly with each other. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4197 OrderAccess::fence(); |
3960 | 4198 return ret; |
4199 } | |
4200 | |
4201 void os::PlatformEvent::unpark() { | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4202 // Transitions for _Event: |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4203 // 0 :=> 1 |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4204 // 1 :=> 1 |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4205 // -1 :=> either 0 or 1; must signal target thread |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4206 // That is, we can safely transition _Event from -1 to either |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4207 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4208 // unpark() calls. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4209 // See also: "Semaphores in Plan 9" by Mullender & Cox |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4210 // |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4211 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4212 // that it will take two back-to-back park() calls for the owning |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4213 // thread to block. This has the benefit of forcing a spurious return |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4214 // from the first park() call after an unpark() call which will help |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4215 // shake out uses of park() and unpark() without condition variables. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4216 |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4217 if (Atomic::xchg(1, &_Event) >= 0) return; |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4218 |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4219 // Wait for the thread associated with the event to vacate |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4220 int status = pthread_mutex_lock(_mutex); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4221 assert_status(status == 0, status, "mutex_lock"); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4222 int AnyWaiters = _nParked; |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4223 assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant"); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4224 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4225 AnyWaiters = 0; |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4226 pthread_cond_signal(_cond); |
3960 | 4227 } |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4228 status = pthread_mutex_unlock(_mutex); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4229 assert_status(status == 0, status, "mutex_unlock"); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4230 if (AnyWaiters != 0) { |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4231 status = pthread_cond_signal(_cond); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4232 assert_status(status == 0, status, "cond_signal"); |
3960 | 4233 } |
4234 | |
4235 // Note that we signal() _after dropping the lock for "immortal" Events. | |
4236 // This is safe and avoids a common class of futile wakeups. In rare | |
4237 // circumstances this can cause a thread to return prematurely from | |
4238 // cond_{timed}wait() but the spurious wakeup is benign and the victim will | |
4239 // simply re-test the condition and re-park itself. | |
4240 } | |
4241 | |
4242 | |
4243 // JSR166 | |
4244 // ------------------------------------------------------- | |
4245 | |
4246 /* | |
4247 * The solaris and bsd implementations of park/unpark are fairly | |
4248 * conservative for now, but can be improved. They currently use a | |
4249 * mutex/condvar pair, plus a a count. | |
4250 * Park decrements count if > 0, else does a condvar wait. Unpark | |
4251 * sets count to 1 and signals condvar. Only one thread ever waits | |
4252 * on the condvar. Contention seen when trying to park implies that someone | |
4253 * is unparking you, so don't wait. And spurious returns are fine, so there | |
4254 * is no need to track notifications. | |
4255 */ | |
4256 | |
4257 #define MAX_SECS 100000000 | |
4258 /* | |
4259 * This code is common to bsd and solaris and will be moved to a | |
4260 * common place in dolphin. | |
4261 * | |
4262 * The passed in time value is either a relative time in nanoseconds | |
4263 * or an absolute time in milliseconds. Either way it has to be unpacked | |
4264 * into suitable seconds and nanoseconds components and stored in the | |
4265 * given timespec structure. | |
4266 * Given time is a 64-bit value and the time_t used in the timespec is only | |
4267 * a signed-32-bit value (except on 64-bit Bsd) we have to watch for | |
4268 * overflow if times way in the future are given. Further on Solaris versions | |
4269 * prior to 10 there is a restriction (see cond_timedwait) that the specified | |
4270 * number of seconds, in abstime, is less than current_time + 100,000,000. | |
4271 * As it will be 28 years before "now + 100000000" will overflow we can | |
4272 * ignore overflow and just impose a hard-limit on seconds using the value | |
4273 * of "now + 100,000,000". This places a limit on the timeout of about 3.17 | |
4274 * years from "now". | |
4275 */ | |
4276 | |
4277 static void unpackTime(struct timespec* absTime, bool isAbsolute, jlong time) { | |
4278 assert (time > 0, "convertTime"); | |
4279 | |
4280 struct timeval now; | |
4281 int status = gettimeofday(&now, NULL); | |
4282 assert(status == 0, "gettimeofday"); | |
4283 | |
4284 time_t max_secs = now.tv_sec + MAX_SECS; | |
4285 | |
4286 if (isAbsolute) { | |
4287 jlong secs = time / 1000; | |
4288 if (secs > max_secs) { | |
4289 absTime->tv_sec = max_secs; | |
4290 } | |
4291 else { | |
4292 absTime->tv_sec = secs; | |
4293 } | |
4294 absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; | |
4295 } | |
4296 else { | |
4297 jlong secs = time / NANOSECS_PER_SEC; | |
4298 if (secs >= MAX_SECS) { | |
4299 absTime->tv_sec = max_secs; | |
4300 absTime->tv_nsec = 0; | |
4301 } | |
4302 else { | |
4303 absTime->tv_sec = now.tv_sec + secs; | |
4304 absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; | |
4305 if (absTime->tv_nsec >= NANOSECS_PER_SEC) { | |
4306 absTime->tv_nsec -= NANOSECS_PER_SEC; | |
4307 ++absTime->tv_sec; // note: this must be <= max_secs | |
4308 } | |
4309 } | |
4310 } | |
4311 assert(absTime->tv_sec >= 0, "tv_sec < 0"); | |
4312 assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs"); | |
4313 assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); | |
4314 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); | |
4315 } | |
4316 | |
4317 void Parker::park(bool isAbsolute, jlong time) { | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4318 // Ideally we'd do something useful while spinning, such |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4319 // as calling unpackTime(). |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4320 |
3960 | 4321 // Optional fast-path check: |
4322 // Return immediately if a permit is available. | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4323 // We depend on Atomic::xchg() having full barrier semantics |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4324 // since we are doing a lock-free update to _counter. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4325 if (Atomic::xchg(0, &_counter) > 0) return; |
3960 | 4326 |
4327 Thread* thread = Thread::current(); | |
4328 assert(thread->is_Java_thread(), "Must be JavaThread"); | |
4329 JavaThread *jt = (JavaThread *)thread; | |
4330 | |
4331 // Optional optimization -- avoid state transitions if there's an interrupt pending. | |
4332 // Check interrupt before trying to wait | |
4333 if (Thread::is_interrupted(thread, false)) { | |
4334 return; | |
4335 } | |
4336 | |
4337 // Next, demultiplex/decode time arguments | |
4338 struct timespec absTime; | |
4339 if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all | |
4340 return; | |
4341 } | |
4342 if (time > 0) { | |
4343 unpackTime(&absTime, isAbsolute, time); | |
4344 } | |
4345 | |
4346 | |
4347 // Enter safepoint region | |
4348 // Beware of deadlocks such as 6317397. | |
4349 // The per-thread Parker:: mutex is a classic leaf-lock. | |
4350 // In particular a thread must never block on the Threads_lock while | |
4351 // holding the Parker:: mutex. If safepoints are pending both the | |
4352 // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock. | |
4353 ThreadBlockInVM tbivm(jt); | |
4354 | |
4355 // Don't wait if cannot get lock since interference arises from | |
4356 // unblocking. Also. check interrupt before trying wait | |
4357 if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) { | |
4358 return; | |
4359 } | |
4360 | |
4361 int status ; | |
4362 if (_counter > 0) { // no wait needed | |
4363 _counter = 0; | |
4364 status = pthread_mutex_unlock(_mutex); | |
4365 assert (status == 0, "invariant") ; | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4366 // Paranoia to ensure our locked and lock-free paths interact |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4367 // correctly with each other and Java-level accesses. |
3960 | 4368 OrderAccess::fence(); |
4369 return; | |
4370 } | |
4371 | |
4372 #ifdef ASSERT | |
4373 // Don't catch signals while blocked; let the running threads have the signals. | |
4374 // (This allows a debugger to break into the running thread.) | |
4375 sigset_t oldsigs; | |
4376 sigset_t* allowdebug_blocked = os::Bsd::allowdebug_blocked_signals(); | |
4377 pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs); | |
4378 #endif | |
4379 | |
4380 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); | |
4381 jt->set_suspend_equivalent(); | |
4382 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() | |
4383 | |
4384 if (time == 0) { | |
4385 status = pthread_cond_wait (_cond, _mutex) ; | |
4386 } else { | |
4387 status = os::Bsd::safe_cond_timedwait (_cond, _mutex, &absTime) ; | |
4388 if (status != 0 && WorkAroundNPTLTimedWaitHang) { | |
4389 pthread_cond_destroy (_cond) ; | |
4390 pthread_cond_init (_cond, NULL); | |
4391 } | |
4392 } | |
4393 assert_status(status == 0 || status == EINTR || | |
4394 status == ETIMEDOUT, | |
4395 status, "cond_timedwait"); | |
4396 | |
4397 #ifdef ASSERT | |
4398 pthread_sigmask(SIG_SETMASK, &oldsigs, NULL); | |
4399 #endif | |
4400 | |
4401 _counter = 0 ; | |
4402 status = pthread_mutex_unlock(_mutex) ; | |
4403 assert_status(status == 0, status, "invariant") ; | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4404 // Paranoia to ensure our locked and lock-free paths interact |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4405 // correctly with each other and Java-level accesses. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4406 OrderAccess::fence(); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7626
diff
changeset
|
4407 |
3960 | 4408 // If externally suspended while waiting, re-suspend |
4409 if (jt->handle_special_suspend_equivalent_condition()) { | |
4410 jt->java_suspend_self(); | |
4411 } | |
4412 } | |
4413 | |
4414 void Parker::unpark() { | |
4415 int s, status ; | |
4416 status = pthread_mutex_lock(_mutex); | |
4417 assert (status == 0, "invariant") ; | |
4418 s = _counter; | |
4419 _counter = 1; | |
4420 if (s < 1) { | |
4421 if (WorkAroundNPTLTimedWaitHang) { | |
4422 status = pthread_cond_signal (_cond) ; | |
4423 assert (status == 0, "invariant") ; | |
4424 status = pthread_mutex_unlock(_mutex); | |
4425 assert (status == 0, "invariant") ; | |
4426 } else { | |
4427 status = pthread_mutex_unlock(_mutex); | |
4428 assert (status == 0, "invariant") ; | |
4429 status = pthread_cond_signal (_cond) ; | |
4430 assert (status == 0, "invariant") ; | |
4431 } | |
4432 } else { | |
4433 pthread_mutex_unlock(_mutex); | |
4434 assert (status == 0, "invariant") ; | |
4435 } | |
4436 } | |
4437 | |
4438 | |
4439 /* Darwin has no "environ" in a dynamic library. */ | |
4440 #ifdef __APPLE__ | |
4441 #include <crt_externs.h> | |
4442 #define environ (*_NSGetEnviron()) | |
4443 #else | |
4444 extern char** environ; | |
4445 #endif | |
4446 | |
4447 // Run the specified command in a separate process. Return its exit value, | |
4448 // or -1 on failure (e.g. can't fork a new process). | |
4449 // Unlike system(), this function can be called from signal handler. It | |
4450 // doesn't block SIGINT et al. | |
4451 int os::fork_and_exec(char* cmd) { | |
4452 const char * argv[4] = {"sh", "-c", cmd, NULL}; | |
4453 | |
4454 // fork() in BsdThreads/NPTL is not async-safe. It needs to run | |
4455 // pthread_atfork handlers and reset pthread library. All we need is a | |
4456 // separate process to execve. Make a direct syscall to fork process. | |
4457 // On IA64 there's no fork syscall, we have to use fork() and hope for | |
4458 // the best... | |
4459 pid_t pid = fork(); | |
4460 | |
4461 if (pid < 0) { | |
4462 // fork failed | |
4463 return -1; | |
4464 | |
4465 } else if (pid == 0) { | |
4466 // child process | |
4467 | |
4468 // execve() in BsdThreads will call pthread_kill_other_threads_np() | |
4469 // first to kill every thread on the thread list. Because this list is | |
4470 // not reset by fork() (see notes above), execve() will instead kill | |
4471 // every thread in the parent process. We know this is the only thread | |
4472 // in the new process, so make a system call directly. | |
4473 // IA64 should use normal execve() from glibc to match the glibc fork() | |
4474 // above. | |
4475 execve("/bin/sh", (char* const*)argv, environ); | |
4476 | |
4477 // execve failed | |
4478 _exit(-1); | |
4479 | |
4480 } else { | |
4481 // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't | |
4482 // care about the actual exit code, for now. | |
4483 | |
4484 int status; | |
4485 | |
4486 // Wait for the child process to exit. This returns immediately if | |
4487 // the child has already exited. */ | |
4488 while (waitpid(pid, &status, 0) < 0) { | |
4489 switch (errno) { | |
4490 case ECHILD: return 0; | |
4491 case EINTR: break; | |
4492 default: return -1; | |
4493 } | |
4494 } | |
4495 | |
4496 if (WIFEXITED(status)) { | |
4497 // The child exited normally; get its exit code. | |
4498 return WEXITSTATUS(status); | |
4499 } else if (WIFSIGNALED(status)) { | |
4500 // The child exited because of a signal | |
4501 // The best value to return is 0x80 + signal number, | |
4502 // because that is what all Unix shells do, and because | |
4503 // it allows callers to distinguish between process exit and | |
4504 // process death by signal. | |
4505 return 0x80 + WTERMSIG(status); | |
4506 } else { | |
4507 // Unknown exit code; pass it through | |
4508 return status; | |
4509 } | |
4510 } | |
4511 } | |
4512 | |
4513 // is_headless_jre() | |
4514 // | |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
4515 // Test for the existence of xawt/libmawt.so or libawt_xawt.so |
3960 | 4516 // in order to report if we are running in a headless jre |
4517 // | |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
4518 // Since JDK8 xawt/libmawt.so was moved into the same directory |
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
4519 // as libawt.so, and renamed libawt_xawt.so |
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
4520 // |
3960 | 4521 bool os::is_headless_jre() { |
4522 struct stat statbuf; | |
4523 char buf[MAXPATHLEN]; | |
4524 char libmawtpath[MAXPATHLEN]; | |
4006 | 4525 const char *xawtstr = "/xawt/libmawt" JNI_LIB_SUFFIX; |
5921 | 4526 const char *new_xawtstr = "/libawt_xawt" JNI_LIB_SUFFIX; |
3960 | 4527 char *p; |
4528 | |
4529 // Get path to libjvm.so | |
4530 os::jvm_path(buf, sizeof(buf)); | |
4531 | |
4532 // Get rid of libjvm.so | |
4533 p = strrchr(buf, '/'); | |
4534 if (p == NULL) return false; | |
4535 else *p = '\0'; | |
4536 | |
4537 // Get rid of client or server | |
4538 p = strrchr(buf, '/'); | |
4539 if (p == NULL) return false; | |
4540 else *p = '\0'; | |
4541 | |
4542 // check xawt/libmawt.so | |
4543 strcpy(libmawtpath, buf); | |
4544 strcat(libmawtpath, xawtstr); | |
4545 if (::stat(libmawtpath, &statbuf) == 0) return false; | |
4546 | |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
4547 // check libawt_xawt.so |
3960 | 4548 strcpy(libmawtpath, buf); |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
4549 strcat(libmawtpath, new_xawtstr); |
3960 | 4550 if (::stat(libmawtpath, &statbuf) == 0) return false; |
4551 | |
4552 return true; | |
4553 } | |
6200
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4554 |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4555 // Get the default path to the core file |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4556 // Returns the length of the string |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4557 int os::get_core_path(char* buffer, size_t bufferSize) { |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4558 int n = jio_snprintf(buffer, bufferSize, "/cores"); |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4559 |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4560 // Truncate if theoretical string was longer than bufferSize |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4561 n = MIN2(n, (int)bufferSize); |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4562 |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4563 return n; |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
4564 } |