Mercurial > hg > graal-jvmci-8
annotate src/os/linux/vm/os_linux.cpp @ 12832:263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
Summary: Don't turn on transparent huge pages (-XX:+UseTransparentHugePages) unless explicitly specified on the command line. This has the effect that large pages are never turned on Linux unless the user has explicitly enabled any of the large pages flags: -XX:+UseLargePages, -XX:+UseTransparentHugePages, -XX:+UseHugeTLBFS, and -XX:+UseSHM.
Reviewed-by: jwilhelm, tschatzl, brutisso
author | stefank |
---|---|
date | Sat, 05 Oct 2013 10:14:58 +0200 |
parents | 06ae47d9d088 |
children | aa6f2ea19d8f |
rev | line source |
---|---|
0 | 1 /* |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1537
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1537
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1537
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 // no precompiled headers |
26 #include "classfile/classLoader.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "classfile/vmSymbols.hpp" | |
29 #include "code/icBuffer.hpp" | |
30 #include "code/vtableStubs.hpp" | |
31 #include "compiler/compileBroker.hpp" | |
7199
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
6966
diff
changeset
|
32 #include "compiler/disassembler.hpp" |
1972 | 33 #include "interpreter/interpreter.hpp" |
34 #include "jvm_linux.h" | |
35 #include "memory/allocation.inline.hpp" | |
36 #include "memory/filemap.hpp" | |
37 #include "mutex_linux.inline.hpp" | |
38 #include "oops/oop.inline.hpp" | |
39 #include "os_share_linux.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" | |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
47 #include "runtime/init.hpp" |
1972 | 48 #include "runtime/java.hpp" |
49 #include "runtime/javaCalls.hpp" | |
50 #include "runtime/mutexLocker.hpp" | |
51 #include "runtime/objectMonitor.hpp" | |
52 #include "runtime/osThread.hpp" | |
53 #include "runtime/perfMemory.hpp" | |
54 #include "runtime/sharedRuntime.hpp" | |
55 #include "runtime/statSampler.hpp" | |
56 #include "runtime/stubRoutines.hpp" | |
7180
f34d701e952e
8003935: Simplify the needed includes for using Thread::current()
stefank
parents:
6966
diff
changeset
|
57 #include "runtime/thread.inline.hpp" |
1972 | 58 #include "runtime/threadCritical.hpp" |
59 #include "runtime/timer.hpp" | |
60 #include "services/attachListener.hpp" | |
8711
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8710
diff
changeset
|
61 #include "services/memTracker.hpp" |
1972 | 62 #include "services/runtimeService.hpp" |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
63 #include "utilities/decoder.hpp" |
1972 | 64 #include "utilities/defaultStream.hpp" |
65 #include "utilities/events.hpp" | |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
66 #include "utilities/elfFile.hpp" |
1972 | 67 #include "utilities/growableArray.hpp" |
68 #include "utilities/vmError.hpp" | |
0 | 69 |
70 // put OS-includes here | |
71 # include <sys/types.h> | |
72 # include <sys/mman.h> | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
73 # include <sys/stat.h> |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
74 # include <sys/select.h> |
0 | 75 # include <pthread.h> |
76 # include <signal.h> | |
77 # include <errno.h> | |
78 # include <dlfcn.h> | |
79 # include <stdio.h> | |
80 # include <unistd.h> | |
81 # include <sys/resource.h> | |
82 # include <pthread.h> | |
83 # include <sys/stat.h> | |
84 # include <sys/time.h> | |
85 # include <sys/times.h> | |
86 # include <sys/utsname.h> | |
87 # include <sys/socket.h> | |
88 # include <sys/wait.h> | |
89 # include <pwd.h> | |
90 # include <poll.h> | |
91 # include <semaphore.h> | |
92 # include <fcntl.h> | |
93 # include <string.h> | |
94 # include <syscall.h> | |
95 # include <sys/sysinfo.h> | |
96 # include <gnu/libc-version.h> | |
97 # include <sys/ipc.h> | |
98 # include <sys/shm.h> | |
99 # include <link.h> | |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
100 # include <stdint.h> |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
101 # include <inttypes.h> |
2033
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
102 # include <sys/ioctl.h> |
0 | 103 |
10372
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
104 // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
105 // getrusage() is prepared to handle the associated failure. |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
106 #ifndef RUSAGE_THREAD |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
107 #define RUSAGE_THREAD (1) /* only the calling thread */ |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
108 #endif |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
109 |
0 | 110 #define MAX_PATH (2 * K) |
111 | |
112 // for timer info max values which include all bits | |
113 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) | |
114 | |
2204
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
115 #define LARGEPAGES_BIT (1 << 6) |
0 | 116 //////////////////////////////////////////////////////////////////////////////// |
117 // global variables | |
118 julong os::Linux::_physical_memory = 0; | |
119 | |
120 address os::Linux::_initial_thread_stack_bottom = NULL; | |
121 uintptr_t os::Linux::_initial_thread_stack_size = 0; | |
122 | |
123 int (*os::Linux::_clock_gettime)(clockid_t, struct timespec *) = NULL; | |
124 int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL; | |
125 Mutex* os::Linux::_createThread_lock = NULL; | |
126 pthread_t os::Linux::_main_thread; | |
127 int os::Linux::_page_size = -1; | |
10164
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
128 const int os::Linux::_vm_default_page_size = (8 * K); |
0 | 129 bool os::Linux::_is_floating_stack = false; |
130 bool os::Linux::_is_NPTL = false; | |
131 bool os::Linux::_supports_fast_thread_cpu_time = false; | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
132 const char * os::Linux::_glibc_version = NULL; |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
133 const char * os::Linux::_libpthread_version = NULL; |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
134 pthread_condattr_t os::Linux::_condattr[1]; |
0 | 135 |
136 static jlong initial_time_count=0; | |
137 | |
138 static int clock_tics_per_sec = 100; | |
139 | |
140 // For diagnostics to print a message once. see run_periodic_checks | |
141 static sigset_t check_signal_done; | |
142 static bool check_signals = true;; | |
143 | |
144 static pid_t _initial_pid = 0; | |
145 | |
146 /* Signal number used to suspend/resume a thread */ | |
147 | |
148 /* do not use any signal number less than SIGSEGV, see 4355769 */ | |
149 static int SR_signum = SIGUSR2; | |
150 sigset_t SR_sigset; | |
151 | |
242 | 152 /* Used to protect dlsym() calls */ |
153 static pthread_mutex_t dl_mutex; | |
154 | |
10405 | 155 // Declarations |
156 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time); | |
157 | |
3802
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
158 #ifdef JAVASE_EMBEDDED |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
159 class MemNotifyThread: public Thread { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
160 friend class VMStructs; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
161 public: |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
162 virtual void run(); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
163 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
164 private: |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
165 static MemNotifyThread* _memnotify_thread; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
166 int _fd; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
167 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
168 public: |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
169 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
170 // Constructor |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
171 MemNotifyThread(int fd); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
172 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
173 // Tester |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
174 bool is_memnotify_thread() const { return true; } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
175 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
176 // Printing |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
177 char* name() const { return (char*)"Linux MemNotify Thread"; } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
178 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
179 // Returns the single instance of the MemNotifyThread |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
180 static MemNotifyThread* memnotify_thread() { return _memnotify_thread; } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
181 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
182 // Create and start the single instance of MemNotifyThread |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
183 static void start(); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
184 }; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
185 #endif // JAVASE_EMBEDDED |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
186 |
0 | 187 // utility functions |
188 | |
189 static int SR_initialize(); | |
190 | |
191 julong os::available_memory() { | |
192 return Linux::available_memory(); | |
193 } | |
194 | |
195 julong os::Linux::available_memory() { | |
196 // values in struct sysinfo are "unsigned long" | |
197 struct sysinfo si; | |
198 sysinfo(&si); | |
199 | |
200 return (julong)si.freeram * si.mem_unit; | |
201 } | |
202 | |
203 julong os::physical_memory() { | |
204 return Linux::physical_memory(); | |
205 } | |
206 | |
207 //////////////////////////////////////////////////////////////////////////////// | |
208 // environment support | |
209 | |
210 bool os::getenv(const char* name, char* buf, int len) { | |
211 const char* val = ::getenv(name); | |
212 if (val != NULL && strlen(val) < (size_t)len) { | |
213 strcpy(buf, val); | |
214 return true; | |
215 } | |
216 if (len > 0) buf[0] = 0; // return a null string | |
217 return false; | |
218 } | |
219 | |
220 | |
221 // Return true if user is running as root. | |
222 | |
223 bool os::have_special_privileges() { | |
224 static bool init = false; | |
225 static bool privileges = false; | |
226 if (!init) { | |
227 privileges = (getuid() != geteuid()) || (getgid() != getegid()); | |
228 init = true; | |
229 } | |
230 return privileges; | |
231 } | |
232 | |
233 | |
234 #ifndef SYS_gettid | |
235 // i386: 224, ia64: 1105, amd64: 186, sparc 143 | |
236 #ifdef __ia64__ | |
237 #define SYS_gettid 1105 | |
238 #elif __i386__ | |
239 #define SYS_gettid 224 | |
240 #elif __amd64__ | |
241 #define SYS_gettid 186 | |
242 #elif __sparc__ | |
243 #define SYS_gettid 143 | |
244 #else | |
245 #error define gettid for the arch | |
246 #endif | |
247 #endif | |
248 | |
249 // Cpu architecture string | |
1010 | 250 #if defined(ZERO) |
251 static char cpu_arch[] = ZERO_LIBARCH; | |
252 #elif defined(IA64) | |
0 | 253 static char cpu_arch[] = "ia64"; |
254 #elif defined(IA32) | |
255 static char cpu_arch[] = "i386"; | |
256 #elif defined(AMD64) | |
257 static char cpu_arch[] = "amd64"; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
258 #elif defined(ARM) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
259 static char cpu_arch[] = "arm"; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
260 #elif defined(PPC) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
261 static char cpu_arch[] = "ppc"; |
0 | 262 #elif defined(SPARC) |
263 # ifdef _LP64 | |
264 static char cpu_arch[] = "sparcv9"; | |
265 # else | |
266 static char cpu_arch[] = "sparc"; | |
267 # endif | |
268 #else | |
269 #error Add appropriate cpu_arch setting | |
270 #endif | |
271 | |
272 | |
273 // pid_t gettid() | |
274 // | |
275 // Returns the kernel thread id of the currently running thread. Kernel | |
276 // thread id is used to access /proc. | |
277 // | |
278 // (Note that getpid() on LinuxThreads returns kernel thread id too; but | |
279 // on NPTL, it returns the same pid for all threads, as required by POSIX.) | |
280 // | |
281 pid_t os::Linux::gettid() { | |
282 int rslt = syscall(SYS_gettid); | |
283 if (rslt == -1) { | |
284 // old kernel, no NPTL support | |
285 return getpid(); | |
286 } else { | |
287 return (pid_t)rslt; | |
288 } | |
289 } | |
290 | |
291 // Most versions of linux have a bug where the number of processors are | |
292 // determined by looking at the /proc file system. In a chroot environment, | |
293 // the system call returns 1. This causes the VM to act as if it is | |
294 // a single processor and elide locking (see is_MP() call). | |
295 static bool unsafe_chroot_detected = false; | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
296 static const char *unstable_chroot_error = "/proc file system not found.\n" |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
297 "Java may be unstable running multithreaded in a chroot " |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
298 "environment on Linux when /proc filesystem is not mounted."; |
0 | 299 |
300 void os::Linux::initialize_system_info() { | |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
1117
diff
changeset
|
301 set_processor_count(sysconf(_SC_NPROCESSORS_CONF)); |
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
1117
diff
changeset
|
302 if (processor_count() == 1) { |
0 | 303 pid_t pid = os::Linux::gettid(); |
304 char fname[32]; | |
305 jio_snprintf(fname, sizeof(fname), "/proc/%d", pid); | |
306 FILE *fp = fopen(fname, "r"); | |
307 if (fp == NULL) { | |
308 unsafe_chroot_detected = true; | |
309 } else { | |
310 fclose(fp); | |
311 } | |
312 } | |
313 _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE); | |
1123
167c2986d91b
6843629: Make current hotspot build part of jdk5 control build
phh
parents:
1117
diff
changeset
|
314 assert(processor_count() > 0, "linux error"); |
0 | 315 } |
316 | |
317 void os::init_system_properties_values() { | |
318 // char arch[12]; | |
319 // sysinfo(SI_ARCHITECTURE, arch, sizeof(arch)); | |
320 | |
321 // The next steps are taken in the product version: | |
322 // | |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
323 // Obtain the JAVA_HOME value from the location of libjvm.so. |
0 | 324 // This library should be located at: |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
325 // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm.so. |
0 | 326 // |
327 // 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
|
328 // assume libjvm.so is installed in a JDK and we use this path. |
0 | 329 // |
330 // Otherwise exit with message: "Could not create the Java virtual machine." | |
331 // | |
332 // The following extra steps are taken in the debugging version: | |
333 // | |
334 // If "/jre/lib/" does NOT appear at the right place in the path | |
335 // instead of exit check for $JAVA_HOME environment variable. | |
336 // | |
337 // 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
|
338 // 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
|
339 // it looks like libjvm.so is installed there |
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
340 // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so. |
0 | 341 // |
342 // Otherwise exit. | |
343 // | |
344 // Important note: if the location of libjvm.so changes this | |
345 // code needs to be changed accordingly. | |
346 | |
347 // The next few definitions allow the code to be verbatim: | |
6197 | 348 #define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal) |
0 | 349 #define getenv(n) ::getenv(n) |
350 | |
351 /* | |
352 * See ld(1): | |
353 * The linker uses the following search paths to locate required | |
354 * shared libraries: | |
355 * 1: ... | |
356 * ... | |
357 * 7: The default directories, normally /lib and /usr/lib. | |
358 */ | |
509
9656bebe85a7
6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents:
477
diff
changeset
|
359 #if defined(AMD64) || defined(_LP64) && (defined(SPARC) || defined(PPC) || defined(S390)) |
9656bebe85a7
6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents:
477
diff
changeset
|
360 #define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib" |
9656bebe85a7
6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents:
477
diff
changeset
|
361 #else |
0 | 362 #define DEFAULT_LIBPATH "/lib:/usr/lib" |
509
9656bebe85a7
6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents:
477
diff
changeset
|
363 #endif |
0 | 364 |
365 #define EXTENSIONS_DIR "/lib/ext" | |
366 #define ENDORSED_DIR "/lib/endorsed" | |
367 #define REG_DIR "/usr/java/packages" | |
368 | |
369 { | |
370 /* sysclasspath, java_home, dll_dir */ | |
371 { | |
372 char *home_path; | |
373 char *dll_path; | |
374 char *pslash; | |
375 char buf[MAXPATHLEN]; | |
376 os::jvm_path(buf, sizeof(buf)); | |
377 | |
378 // Found the full path to libjvm.so. | |
379 // Now cut the path to <java_home>/jre if we can. | |
380 *(strrchr(buf, '/')) = '\0'; /* get rid of /libjvm.so */ | |
381 pslash = strrchr(buf, '/'); | |
382 if (pslash != NULL) | |
383 *pslash = '\0'; /* get rid of /{client|server|hotspot} */ | |
384 dll_path = malloc(strlen(buf) + 1); | |
385 if (dll_path == NULL) | |
386 return; | |
387 strcpy(dll_path, buf); | |
388 Arguments::set_dll_dir(dll_path); | |
389 | |
390 if (pslash != NULL) { | |
391 pslash = strrchr(buf, '/'); | |
392 if (pslash != NULL) { | |
393 *pslash = '\0'; /* get rid of /<arch> */ | |
394 pslash = strrchr(buf, '/'); | |
395 if (pslash != NULL) | |
396 *pslash = '\0'; /* get rid of /lib */ | |
397 } | |
398 } | |
399 | |
400 home_path = malloc(strlen(buf) + 1); | |
401 if (home_path == NULL) | |
402 return; | |
403 strcpy(home_path, buf); | |
404 Arguments::set_java_home(home_path); | |
405 | |
406 if (!set_boot_path('/', ':')) | |
407 return; | |
408 } | |
409 | |
410 /* | |
411 * Where to look for native libraries | |
412 * | |
413 * Note: Due to a legacy implementation, most of the library path | |
414 * is set in the launcher. This was to accomodate linking restrictions | |
415 * on legacy Linux implementations (which are no longer supported). | |
416 * Eventually, all the library path setting will be done here. | |
417 * | |
418 * However, to prevent the proliferation of improperly built native | |
419 * libraries, the new path component /usr/java/packages is added here. | |
420 * Eventually, all the library path setting will be done here. | |
421 */ | |
422 { | |
423 char *ld_library_path; | |
424 | |
425 /* | |
426 * Construct the invariant part of ld_library_path. Note that the | |
427 * space for the colon and the trailing null are provided by the | |
428 * nulls included by the sizeof operator (so actually we allocate | |
429 * a byte more than necessary). | |
430 */ | |
431 ld_library_path = (char *) malloc(sizeof(REG_DIR) + sizeof("/lib/") + | |
432 strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH)); | |
433 sprintf(ld_library_path, REG_DIR "/lib/%s:" DEFAULT_LIBPATH, cpu_arch); | |
434 | |
435 /* | |
436 * Get the user setting of LD_LIBRARY_PATH, and prepended it. It | |
437 * should always exist (until the legacy problem cited above is | |
438 * addressed). | |
439 */ | |
440 char *v = getenv("LD_LIBRARY_PATH"); | |
441 if (v != NULL) { | |
442 char *t = ld_library_path; | |
443 /* That's +1 for the colon and +1 for the trailing '\0' */ | |
444 ld_library_path = (char *) malloc(strlen(v) + 1 + strlen(t) + 1); | |
445 sprintf(ld_library_path, "%s:%s", v, t); | |
446 } | |
447 Arguments::set_library_path(ld_library_path); | |
448 } | |
449 | |
450 /* | |
451 * Extensions directories. | |
452 * | |
453 * Note that the space for the colon and the trailing null are provided | |
454 * by the nulls included by the sizeof operator (so actually one byte more | |
455 * than necessary is allocated). | |
456 */ | |
457 { | |
458 char *buf = malloc(strlen(Arguments::get_java_home()) + | |
459 sizeof(EXTENSIONS_DIR) + sizeof(REG_DIR) + sizeof(EXTENSIONS_DIR)); | |
460 sprintf(buf, "%s" EXTENSIONS_DIR ":" REG_DIR EXTENSIONS_DIR, | |
461 Arguments::get_java_home()); | |
462 Arguments::set_ext_dirs(buf); | |
463 } | |
464 | |
465 /* Endorsed standards default directory. */ | |
466 { | |
467 char * buf; | |
468 buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR)); | |
469 sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home()); | |
470 Arguments::set_endorsed_dirs(buf); | |
471 } | |
472 } | |
473 | |
474 #undef malloc | |
475 #undef getenv | |
476 #undef EXTENSIONS_DIR | |
477 #undef ENDORSED_DIR | |
478 | |
479 // Done | |
480 return; | |
481 } | |
482 | |
483 //////////////////////////////////////////////////////////////////////////////// | |
484 // breakpoint support | |
485 | |
486 void os::breakpoint() { | |
487 BREAKPOINT; | |
488 } | |
489 | |
490 extern "C" void breakpoint() { | |
491 // use debugger to set breakpoint here | |
492 } | |
493 | |
494 //////////////////////////////////////////////////////////////////////////////// | |
495 // signal support | |
496 | |
497 debug_only(static bool signal_sets_initialized = false); | |
498 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs; | |
499 | |
500 bool os::Linux::is_sig_ignored(int sig) { | |
501 struct sigaction oact; | |
502 sigaction(sig, (struct sigaction*)NULL, &oact); | |
503 void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction) | |
504 : CAST_FROM_FN_PTR(void*, oact.sa_handler); | |
505 if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) | |
506 return true; | |
507 else | |
508 return false; | |
509 } | |
510 | |
511 void os::Linux::signal_sets_init() { | |
512 // Should also have an assertion stating we are still single-threaded. | |
513 assert(!signal_sets_initialized, "Already initialized"); | |
514 // Fill in signals that are necessarily unblocked for all threads in | |
515 // the VM. Currently, we unblock the following signals: | |
516 // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden | |
517 // by -Xrs (=ReduceSignalUsage)); | |
518 // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all | |
519 // other threads. The "ReduceSignalUsage" boolean tells us not to alter | |
520 // the dispositions or masks wrt these signals. | |
521 // Programs embedding the VM that want to use the above signals for their | |
522 // own purposes must, at this time, use the "-Xrs" option to prevent | |
523 // interference with shutdown hooks and BREAK_SIGNAL thread dumping. | |
524 // (See bug 4345157, and other related bugs). | |
525 // In reality, though, unblocking these signals is really a nop, since | |
526 // these signals are not blocked by default. | |
527 sigemptyset(&unblocked_sigs); | |
528 sigemptyset(&allowdebug_blocked_sigs); | |
529 sigaddset(&unblocked_sigs, SIGILL); | |
530 sigaddset(&unblocked_sigs, SIGSEGV); | |
531 sigaddset(&unblocked_sigs, SIGBUS); | |
532 sigaddset(&unblocked_sigs, SIGFPE); | |
533 sigaddset(&unblocked_sigs, SR_signum); | |
534 | |
535 if (!ReduceSignalUsage) { | |
536 if (!os::Linux::is_sig_ignored(SHUTDOWN1_SIGNAL)) { | |
537 sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL); | |
538 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL); | |
539 } | |
540 if (!os::Linux::is_sig_ignored(SHUTDOWN2_SIGNAL)) { | |
541 sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL); | |
542 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL); | |
543 } | |
544 if (!os::Linux::is_sig_ignored(SHUTDOWN3_SIGNAL)) { | |
545 sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL); | |
546 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL); | |
547 } | |
548 } | |
549 // Fill in signals that are blocked by all but the VM thread. | |
550 sigemptyset(&vm_sigs); | |
551 if (!ReduceSignalUsage) | |
552 sigaddset(&vm_sigs, BREAK_SIGNAL); | |
553 debug_only(signal_sets_initialized = true); | |
554 | |
555 } | |
556 | |
557 // These are signals that are unblocked while a thread is running Java. | |
558 // (For some reason, they get blocked by default.) | |
559 sigset_t* os::Linux::unblocked_signals() { | |
560 assert(signal_sets_initialized, "Not initialized"); | |
561 return &unblocked_sigs; | |
562 } | |
563 | |
564 // These are the signals that are blocked while a (non-VM) thread is | |
565 // running Java. Only the VM thread handles these signals. | |
566 sigset_t* os::Linux::vm_signals() { | |
567 assert(signal_sets_initialized, "Not initialized"); | |
568 return &vm_sigs; | |
569 } | |
570 | |
571 // These are signals that are blocked during cond_wait to allow debugger in | |
572 sigset_t* os::Linux::allowdebug_blocked_signals() { | |
573 assert(signal_sets_initialized, "Not initialized"); | |
574 return &allowdebug_blocked_sigs; | |
575 } | |
576 | |
577 void os::Linux::hotspot_sigmask(Thread* thread) { | |
578 | |
579 //Save caller's signal mask before setting VM signal mask | |
580 sigset_t caller_sigmask; | |
581 pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask); | |
582 | |
583 OSThread* osthread = thread->osthread(); | |
584 osthread->set_caller_sigmask(caller_sigmask); | |
585 | |
586 pthread_sigmask(SIG_UNBLOCK, os::Linux::unblocked_signals(), NULL); | |
587 | |
588 if (!ReduceSignalUsage) { | |
589 if (thread->is_VM_thread()) { | |
590 // Only the VM thread handles BREAK_SIGNAL ... | |
591 pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL); | |
592 } else { | |
593 // ... all other threads block BREAK_SIGNAL | |
594 pthread_sigmask(SIG_BLOCK, vm_signals(), NULL); | |
595 } | |
596 } | |
597 } | |
598 | |
599 ////////////////////////////////////////////////////////////////////////////// | |
600 // detecting pthread library | |
601 | |
602 void os::Linux::libpthread_init() { | |
603 // Save glibc and pthread version strings. Note that _CS_GNU_LIBC_VERSION | |
604 // and _CS_GNU_LIBPTHREAD_VERSION are supported in glibc >= 2.3.2. Use a | |
605 // generic name for earlier versions. | |
606 // Define macros here so we can build HotSpot on old systems. | |
607 # ifndef _CS_GNU_LIBC_VERSION | |
608 # define _CS_GNU_LIBC_VERSION 2 | |
609 # endif | |
610 # ifndef _CS_GNU_LIBPTHREAD_VERSION | |
611 # define _CS_GNU_LIBPTHREAD_VERSION 3 | |
612 # endif | |
613 | |
614 size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0); | |
615 if (n > 0) { | |
6197 | 616 char *str = (char *)malloc(n, mtInternal); |
0 | 617 confstr(_CS_GNU_LIBC_VERSION, str, n); |
618 os::Linux::set_glibc_version(str); | |
619 } else { | |
620 // _CS_GNU_LIBC_VERSION is not supported, try gnu_get_libc_version() | |
621 static char _gnu_libc_version[32]; | |
622 jio_snprintf(_gnu_libc_version, sizeof(_gnu_libc_version), | |
623 "glibc %s %s", gnu_get_libc_version(), gnu_get_libc_release()); | |
624 os::Linux::set_glibc_version(_gnu_libc_version); | |
625 } | |
626 | |
627 n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0); | |
628 if (n > 0) { | |
6197 | 629 char *str = (char *)malloc(n, mtInternal); |
0 | 630 confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n); |
631 // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells | |
632 // us "NPTL-0.29" even we are running with LinuxThreads. Check if this | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
633 // is the case. LinuxThreads has a hard limit on max number of threads. |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
634 // So sysconf(_SC_THREAD_THREADS_MAX) will return a positive value. |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
635 // On the other hand, NPTL does not have such a limit, sysconf() |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
636 // will return -1 and errno is not changed. Check if it is really NPTL. |
0 | 637 if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 && |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
638 strstr(str, "NPTL") && |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
639 sysconf(_SC_THREAD_THREADS_MAX) > 0) { |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
640 free(str); |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
641 os::Linux::set_libpthread_version("linuxthreads"); |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
642 } else { |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
643 os::Linux::set_libpthread_version(str); |
0 | 644 } |
645 } else { | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
646 // glibc before 2.3.2 only has LinuxThreads. |
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
647 os::Linux::set_libpthread_version("linuxthreads"); |
0 | 648 } |
649 | |
650 if (strstr(libpthread_version(), "NPTL")) { | |
651 os::Linux::set_is_NPTL(); | |
652 } else { | |
653 os::Linux::set_is_LinuxThreads(); | |
654 } | |
655 | |
656 // LinuxThreads have two flavors: floating-stack mode, which allows variable | |
657 // stack size; and fixed-stack mode. NPTL is always floating-stack. | |
658 if (os::Linux::is_NPTL() || os::Linux::supports_variable_stack_size()) { | |
659 os::Linux::set_is_floating_stack(); | |
660 } | |
661 } | |
662 | |
663 ///////////////////////////////////////////////////////////////////////////// | |
664 // thread stack | |
665 | |
666 // Force Linux kernel to expand current thread stack. If "bottom" is close | |
667 // to the stack guard, caller should block all signals. | |
668 // | |
669 // MAP_GROWSDOWN: | |
670 // A special mmap() flag that is used to implement thread stacks. It tells | |
671 // kernel that the memory region should extend downwards when needed. This | |
672 // allows early versions of LinuxThreads to only mmap the first few pages | |
673 // when creating a new thread. Linux kernel will automatically expand thread | |
674 // stack as needed (on page faults). | |
675 // | |
676 // However, because the memory region of a MAP_GROWSDOWN stack can grow on | |
677 // demand, if a page fault happens outside an already mapped MAP_GROWSDOWN | |
678 // region, it's hard to tell if the fault is due to a legitimate stack | |
679 // access or because of reading/writing non-exist memory (e.g. buffer | |
680 // overrun). As a rule, if the fault happens below current stack pointer, | |
681 // Linux kernel does not expand stack, instead a SIGSEGV is sent to the | |
682 // application (see Linux kernel fault.c). | |
683 // | |
684 // This Linux feature can cause SIGSEGV when VM bangs thread stack for | |
685 // stack overflow detection. | |
686 // | |
687 // Newer version of LinuxThreads (since glibc-2.2, or, RH-7.x) and NPTL do | |
688 // not use this flag. However, the stack of initial thread is not created | |
689 // by pthread, it is still MAP_GROWSDOWN. Also it's possible (though | |
690 // unlikely) that user code can create a thread with MAP_GROWSDOWN stack | |
691 // and then attach the thread to JVM. | |
692 // | |
693 // To get around the problem and allow stack banging on Linux, we need to | |
694 // manually expand thread stack after receiving the SIGSEGV. | |
695 // | |
696 // There are two ways to expand thread stack to address "bottom", we used | |
697 // both of them in JVM before 1.5: | |
698 // 1. adjust stack pointer first so that it is below "bottom", and then | |
699 // touch "bottom" | |
700 // 2. mmap() the page in question | |
701 // | |
702 // Now alternate signal stack is gone, it's harder to use 2. For instance, | |
703 // if current sp is already near the lower end of page 101, and we need to | |
704 // call mmap() to map page 100, it is possible that part of the mmap() frame | |
705 // will be placed in page 100. When page 100 is mapped, it is zero-filled. | |
706 // That will destroy the mmap() frame and cause VM to crash. | |
707 // | |
708 // The following code works by adjusting sp first, then accessing the "bottom" | |
709 // page to force a page fault. Linux kernel will then automatically expand the | |
710 // stack mapping. | |
711 // | |
712 // _expand_stack_to() assumes its frame size is less than page size, which | |
713 // should always be true if the function is not inlined. | |
714 | |
715 #if __GNUC__ < 3 // gcc 2.x does not support noinline attribute | |
716 #define NOINLINE | |
717 #else | |
718 #define NOINLINE __attribute__ ((noinline)) | |
719 #endif | |
720 | |
721 static void _expand_stack_to(address bottom) NOINLINE; | |
722 | |
723 static void _expand_stack_to(address bottom) { | |
724 address sp; | |
725 size_t size; | |
726 volatile char *p; | |
727 | |
728 // Adjust bottom to point to the largest address within the same page, it | |
729 // gives us a one-page buffer if alloca() allocates slightly more memory. | |
730 bottom = (address)align_size_down((uintptr_t)bottom, os::Linux::page_size()); | |
731 bottom += os::Linux::page_size() - 1; | |
732 | |
733 // sp might be slightly above current stack pointer; if that's the case, we | |
734 // will alloca() a little more space than necessary, which is OK. Don't use | |
735 // os::current_stack_pointer(), as its result can be slightly below current | |
736 // stack pointer, causing us to not alloca enough to reach "bottom". | |
737 sp = (address)&sp; | |
738 | |
739 if (sp > bottom) { | |
740 size = sp - bottom; | |
741 p = (volatile char *)alloca(size); | |
742 assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?"); | |
743 p[0] = '\0'; | |
744 } | |
745 } | |
746 | |
747 bool os::Linux::manually_expand_stack(JavaThread * t, address addr) { | |
748 assert(t!=NULL, "just checking"); | |
749 assert(t->osthread()->expanding_stack(), "expand should be set"); | |
750 assert(t->stack_base() != NULL, "stack_base was not initialized"); | |
751 | |
752 if (addr < t->stack_base() && addr >= t->stack_yellow_zone_base()) { | |
753 sigset_t mask_all, old_sigset; | |
754 sigfillset(&mask_all); | |
755 pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset); | |
756 _expand_stack_to(addr); | |
757 pthread_sigmask(SIG_SETMASK, &old_sigset, NULL); | |
758 return true; | |
759 } | |
760 return false; | |
761 } | |
762 | |
763 ////////////////////////////////////////////////////////////////////////////// | |
764 // create new thread | |
765 | |
766 static address highest_vm_reserved_address(); | |
767 | |
768 // check if it's safe to start a new thread | |
769 static bool _thread_safety_check(Thread* thread) { | |
770 if (os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack()) { | |
771 // Fixed stack LinuxThreads (SuSE Linux/x86, and some versions of Redhat) | |
772 // Heap is mmap'ed at lower end of memory space. Thread stacks are | |
773 // allocated (MAP_FIXED) from high address space. Every thread stack | |
774 // occupies a fixed size slot (usually 2Mbytes, but user can change | |
775 // it to other values if they rebuild LinuxThreads). | |
776 // | |
777 // Problem with MAP_FIXED is that mmap() can still succeed even part of | |
778 // the memory region has already been mmap'ed. That means if we have too | |
779 // many threads and/or very large heap, eventually thread stack will | |
780 // collide with heap. | |
781 // | |
782 // Here we try to prevent heap/stack collision by comparing current | |
783 // stack bottom with the highest address that has been mmap'ed by JVM | |
784 // plus a safety margin for memory maps created by native code. | |
785 // | |
786 // This feature can be disabled by setting ThreadSafetyMargin to 0 | |
787 // | |
788 if (ThreadSafetyMargin > 0) { | |
789 address stack_bottom = os::current_stack_base() - os::current_stack_size(); | |
790 | |
791 // not safe if our stack extends below the safety margin | |
792 return stack_bottom - ThreadSafetyMargin >= highest_vm_reserved_address(); | |
793 } else { | |
794 return true; | |
795 } | |
796 } else { | |
797 // Floating stack LinuxThreads or NPTL: | |
798 // Unlike fixed stack LinuxThreads, thread stacks are not MAP_FIXED. When | |
799 // there's not enough space left, pthread_create() will fail. If we come | |
800 // here, that means enough space has been reserved for stack. | |
801 return true; | |
802 } | |
803 } | |
804 | |
805 // Thread start routine for all newly created threads | |
806 static void *java_start(Thread *thread) { | |
807 // Try to randomize the cache line index of hot stack frames. | |
808 // This helps when threads of the same stack traces evict each other's | |
809 // cache lines. The threads can be either from the same JVM instance, or | |
810 // from different JVM instances. The benefit is especially true for | |
811 // processors with hyperthreading technology. | |
812 static int counter = 0; | |
813 int pid = os::current_process_id(); | |
814 alloca(((pid ^ counter++) & 7) * 128); | |
815 | |
816 ThreadLocalStorage::set_thread(thread); | |
817 | |
818 OSThread* osthread = thread->osthread(); | |
819 Monitor* sync = osthread->startThread_lock(); | |
820 | |
821 // non floating stack LinuxThreads needs extra check, see above | |
822 if (!_thread_safety_check(thread)) { | |
823 // notify parent thread | |
824 MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); | |
825 osthread->set_state(ZOMBIE); | |
826 sync->notify_all(); | |
827 return NULL; | |
828 } | |
829 | |
830 // thread_id is kernel thread id (similar to Solaris LWP id) | |
831 osthread->set_thread_id(os::Linux::gettid()); | |
832 | |
833 if (UseNUMA) { | |
834 int lgrp_id = os::numa_get_group_id(); | |
835 if (lgrp_id != -1) { | |
836 thread->set_lgrp_id(lgrp_id); | |
837 } | |
838 } | |
839 // initialize signal mask for this thread | |
840 os::Linux::hotspot_sigmask(thread); | |
841 | |
842 // initialize floating point control register | |
843 os::Linux::init_thread_fpu_state(); | |
844 | |
845 // handshaking with parent thread | |
846 { | |
847 MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); | |
848 | |
849 // notify parent thread | |
850 osthread->set_state(INITIALIZED); | |
851 sync->notify_all(); | |
852 | |
853 // wait until os::start_thread() | |
854 while (osthread->get_state() == INITIALIZED) { | |
855 sync->wait(Mutex::_no_safepoint_check_flag); | |
856 } | |
857 } | |
858 | |
859 // call one more level start routine | |
860 thread->run(); | |
861 | |
862 return 0; | |
863 } | |
864 | |
865 bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { | |
866 assert(thread->osthread() == NULL, "caller responsible"); | |
867 | |
868 // Allocate the OSThread object | |
869 OSThread* osthread = new OSThread(NULL, NULL); | |
870 if (osthread == NULL) { | |
871 return false; | |
872 } | |
873 | |
874 // set the correct thread state | |
875 osthread->set_thread_type(thr_type); | |
876 | |
877 // Initial state is ALLOCATED but not INITIALIZED | |
878 osthread->set_state(ALLOCATED); | |
879 | |
880 thread->set_osthread(osthread); | |
881 | |
882 // init thread attributes | |
883 pthread_attr_t attr; | |
884 pthread_attr_init(&attr); | |
885 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | |
886 | |
887 // stack size | |
888 if (os::Linux::supports_variable_stack_size()) { | |
889 // calculate stack size if it's not specified by caller | |
890 if (stack_size == 0) { | |
891 stack_size = os::Linux::default_stack_size(thr_type); | |
892 | |
893 switch (thr_type) { | |
894 case os::java_thread: | |
1867
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
895 // Java threads use ThreadStackSize which default value can be |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
896 // changed with the flag -Xss |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
897 assert (JavaThread::stack_size_at_create() > 0, "this should be set"); |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
898 stack_size = JavaThread::stack_size_at_create(); |
0 | 899 break; |
900 case os::compiler_thread: | |
901 if (CompilerThreadStackSize > 0) { | |
902 stack_size = (size_t)(CompilerThreadStackSize * K); | |
903 break; | |
904 } // else fall through: | |
905 // use VMThreadStackSize if CompilerThreadStackSize is not defined | |
906 case os::vm_thread: | |
907 case os::pgc_thread: | |
908 case os::cgc_thread: | |
909 case os::watcher_thread: | |
910 if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K); | |
911 break; | |
912 } | |
913 } | |
914 | |
915 stack_size = MAX2(stack_size, os::Linux::min_stack_allowed); | |
916 pthread_attr_setstacksize(&attr, stack_size); | |
917 } else { | |
918 // let pthread_create() pick the default value. | |
919 } | |
920 | |
921 // glibc guard page | |
922 pthread_attr_setguardsize(&attr, os::Linux::default_guard_size(thr_type)); | |
923 | |
924 ThreadState state; | |
925 | |
926 { | |
927 // Serialize thread creation if we are running with fixed stack LinuxThreads | |
928 bool lock = os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack(); | |
929 if (lock) { | |
930 os::Linux::createThread_lock()->lock_without_safepoint_check(); | |
931 } | |
932 | |
933 pthread_t tid; | |
934 int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); | |
935 | |
936 pthread_attr_destroy(&attr); | |
937 | |
938 if (ret != 0) { | |
939 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
940 perror("pthread_create()"); | |
941 } | |
942 // Need to clean up stuff we've allocated so far | |
943 thread->set_osthread(NULL); | |
944 delete osthread; | |
945 if (lock) os::Linux::createThread_lock()->unlock(); | |
946 return false; | |
947 } | |
948 | |
949 // Store pthread info into the OSThread | |
950 osthread->set_pthread_id(tid); | |
951 | |
952 // Wait until child thread is either initialized or aborted | |
953 { | |
954 Monitor* sync_with_child = osthread->startThread_lock(); | |
955 MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag); | |
956 while ((state = osthread->get_state()) == ALLOCATED) { | |
957 sync_with_child->wait(Mutex::_no_safepoint_check_flag); | |
958 } | |
959 } | |
960 | |
961 if (lock) { | |
962 os::Linux::createThread_lock()->unlock(); | |
963 } | |
964 } | |
965 | |
966 // Aborted due to thread limit being reached | |
967 if (state == ZOMBIE) { | |
968 thread->set_osthread(NULL); | |
969 delete osthread; | |
970 return false; | |
971 } | |
972 | |
973 // The thread is returned suspended (in state INITIALIZED), | |
974 // and is started higher up in the call chain | |
975 assert(state == INITIALIZED, "race condition"); | |
976 return true; | |
977 } | |
978 | |
979 ///////////////////////////////////////////////////////////////////////////// | |
980 // attach existing thread | |
981 | |
982 // bootstrap the main thread | |
983 bool os::create_main_thread(JavaThread* thread) { | |
984 assert(os::Linux::_main_thread == pthread_self(), "should be called inside main thread"); | |
985 return create_attached_thread(thread); | |
986 } | |
987 | |
988 bool os::create_attached_thread(JavaThread* thread) { | |
989 #ifdef ASSERT | |
990 thread->verify_not_published(); | |
991 #endif | |
992 | |
993 // Allocate the OSThread object | |
994 OSThread* osthread = new OSThread(NULL, NULL); | |
995 | |
996 if (osthread == NULL) { | |
997 return false; | |
998 } | |
999 | |
1000 // Store pthread info into the OSThread | |
1001 osthread->set_thread_id(os::Linux::gettid()); | |
1002 osthread->set_pthread_id(::pthread_self()); | |
1003 | |
1004 // initialize floating point control register | |
1005 os::Linux::init_thread_fpu_state(); | |
1006 | |
1007 // Initial thread state is RUNNABLE | |
1008 osthread->set_state(RUNNABLE); | |
1009 | |
1010 thread->set_osthread(osthread); | |
1011 | |
1012 if (UseNUMA) { | |
1013 int lgrp_id = os::numa_get_group_id(); | |
1014 if (lgrp_id != -1) { | |
1015 thread->set_lgrp_id(lgrp_id); | |
1016 } | |
1017 } | |
1018 | |
1019 if (os::Linux::is_initial_thread()) { | |
1020 // If current thread is initial thread, its stack is mapped on demand, | |
1021 // see notes about MAP_GROWSDOWN. Here we try to force kernel to map | |
1022 // the entire stack region to avoid SEGV in stack banging. | |
1023 // It is also useful to get around the heap-stack-gap problem on SuSE | |
1024 // kernel (see 4821821 for details). We first expand stack to the top | |
1025 // of yellow zone, then enable stack yellow zone (order is significant, | |
1026 // enabling yellow zone first will crash JVM on SuSE Linux), so there | |
1027 // is no gap between the last two virtual memory regions. | |
1028 | |
1029 JavaThread *jt = (JavaThread *)thread; | |
1030 address addr = jt->stack_yellow_zone_base(); | |
1031 assert(addr != NULL, "initialization problem?"); | |
1032 assert(jt->stack_available(addr) > 0, "stack guard should not be enabled"); | |
1033 | |
1034 osthread->set_expanding_stack(); | |
1035 os::Linux::manually_expand_stack(jt, addr); | |
1036 osthread->clear_expanding_stack(); | |
1037 } | |
1038 | |
1039 // initialize signal mask for this thread | |
1040 // and save the caller's signal mask | |
1041 os::Linux::hotspot_sigmask(thread); | |
1042 | |
1043 return true; | |
1044 } | |
1045 | |
1046 void os::pd_start_thread(Thread* thread) { | |
1047 OSThread * osthread = thread->osthread(); | |
1048 assert(osthread->get_state() != INITIALIZED, "just checking"); | |
1049 Monitor* sync_with_child = osthread->startThread_lock(); | |
1050 MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag); | |
1051 sync_with_child->notify(); | |
1052 } | |
1053 | |
1054 // Free Linux resources related to the OSThread | |
1055 void os::free_thread(OSThread* osthread) { | |
1056 assert(osthread != NULL, "osthread not set"); | |
1057 | |
1058 if (Thread::current()->osthread() == osthread) { | |
1059 // Restore caller's signal mask | |
1060 sigset_t sigmask = osthread->caller_sigmask(); | |
1061 pthread_sigmask(SIG_SETMASK, &sigmask, NULL); | |
1062 } | |
1063 | |
1064 delete osthread; | |
1065 } | |
1066 | |
1067 ////////////////////////////////////////////////////////////////////////////// | |
1068 // thread local storage | |
1069 | |
1070 int os::allocate_thread_local_storage() { | |
1071 pthread_key_t key; | |
1072 int rslt = pthread_key_create(&key, NULL); | |
1073 assert(rslt == 0, "cannot allocate thread local storage"); | |
1074 return (int)key; | |
1075 } | |
1076 | |
1077 // Note: This is currently not used by VM, as we don't destroy TLS key | |
1078 // on VM exit. | |
1079 void os::free_thread_local_storage(int index) { | |
1080 int rslt = pthread_key_delete((pthread_key_t)index); | |
1081 assert(rslt == 0, "invalid index"); | |
1082 } | |
1083 | |
1084 void os::thread_local_storage_at_put(int index, void* value) { | |
1085 int rslt = pthread_setspecific((pthread_key_t)index, value); | |
1086 assert(rslt == 0, "pthread_setspecific failed"); | |
1087 } | |
1088 | |
1089 extern "C" Thread* get_thread() { | |
1090 return ThreadLocalStorage::thread(); | |
1091 } | |
1092 | |
1093 ////////////////////////////////////////////////////////////////////////////// | |
1094 // initial thread | |
1095 | |
1096 // Check if current thread is the initial thread, similar to Solaris thr_main. | |
1097 bool os::Linux::is_initial_thread(void) { | |
1098 char dummy; | |
1099 // If called before init complete, thread stack bottom will be null. | |
1100 // Can be called if fatal error occurs before initialization. | |
1101 if (initial_thread_stack_bottom() == NULL) return false; | |
1102 assert(initial_thread_stack_bottom() != NULL && | |
1103 initial_thread_stack_size() != 0, | |
1104 "os::init did not locate initial thread's stack region"); | |
1105 if ((address)&dummy >= initial_thread_stack_bottom() && | |
1106 (address)&dummy < initial_thread_stack_bottom() + initial_thread_stack_size()) | |
1107 return true; | |
1108 else return false; | |
1109 } | |
1110 | |
1111 // Find the virtual memory area that contains addr | |
1112 static bool find_vma(address addr, address* vma_low, address* vma_high) { | |
1113 FILE *fp = fopen("/proc/self/maps", "r"); | |
1114 if (fp) { | |
1115 address low, high; | |
1116 while (!feof(fp)) { | |
1117 if (fscanf(fp, "%p-%p", &low, &high) == 2) { | |
1118 if (low <= addr && addr < high) { | |
1119 if (vma_low) *vma_low = low; | |
1120 if (vma_high) *vma_high = high; | |
1121 fclose (fp); | |
1122 return true; | |
1123 } | |
1124 } | |
1125 for (;;) { | |
1126 int ch = fgetc(fp); | |
1127 if (ch == EOF || ch == (int)'\n') break; | |
1128 } | |
1129 } | |
1130 fclose(fp); | |
1131 } | |
1132 return false; | |
1133 } | |
1134 | |
1135 // Locate initial thread stack. This special handling of initial thread stack | |
1136 // is needed because pthread_getattr_np() on most (all?) Linux distros returns | |
1137 // bogus value for initial thread. | |
1138 void os::Linux::capture_initial_stack(size_t max_size) { | |
1139 // stack size is the easy part, get it from RLIMIT_STACK | |
1140 size_t stack_size; | |
1141 struct rlimit rlim; | |
1142 getrlimit(RLIMIT_STACK, &rlim); | |
1143 stack_size = rlim.rlim_cur; | |
1144 | |
1145 // 6308388: a bug in ld.so will relocate its own .data section to the | |
1146 // lower end of primordial stack; reduce ulimit -s value a little bit | |
1147 // so we won't install guard page on ld.so's data section. | |
1148 stack_size -= 2 * page_size(); | |
1149 | |
1150 // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat | |
1151 // 7.1, in both cases we will get 2G in return value. | |
1152 // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0, | |
1153 // SuSE 7.2, Debian) can not handle alternate signal stack correctly | |
1154 // for initial thread if its stack size exceeds 6M. Cap it at 2M, | |
1155 // in case other parts in glibc still assumes 2M max stack size. | |
1156 // FIXME: alt signal stack is gone, maybe we can relax this constraint? | |
1157 // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small | |
7994 | 1158 if (stack_size > 2 * K * K IA64_ONLY(*2)) |
1159 stack_size = 2 * K * K IA64_ONLY(*2); | |
0 | 1160 // Try to figure out where the stack base (top) is. This is harder. |
1161 // | |
1162 // When an application is started, glibc saves the initial stack pointer in | |
1163 // a global variable "__libc_stack_end", which is then used by system | |
1164 // libraries. __libc_stack_end should be pretty close to stack top. The | |
1165 // variable is available since the very early days. However, because it is | |
1166 // a private interface, it could disappear in the future. | |
1167 // | |
1168 // Linux kernel saves start_stack information in /proc/<pid>/stat. Similar | |
1169 // to __libc_stack_end, it is very close to stack top, but isn't the real | |
1170 // stack top. Note that /proc may not exist if VM is running as a chroot | |
1171 // program, so reading /proc/<pid>/stat could fail. Also the contents of | |
1172 // /proc/<pid>/stat could change in the future (though unlikely). | |
1173 // | |
1174 // We try __libc_stack_end first. If that doesn't work, look for | |
1175 // /proc/<pid>/stat. If neither of them works, we use current stack pointer | |
1176 // as a hint, which should work well in most cases. | |
1177 | |
1178 uintptr_t stack_start; | |
1179 | |
1180 // try __libc_stack_end first | |
1181 uintptr_t *p = (uintptr_t *)dlsym(RTLD_DEFAULT, "__libc_stack_end"); | |
1182 if (p && *p) { | |
1183 stack_start = *p; | |
1184 } else { | |
1185 // see if we can get the start_stack field from /proc/self/stat | |
1186 FILE *fp; | |
1187 int pid; | |
1188 char state; | |
1189 int ppid; | |
1190 int pgrp; | |
1191 int session; | |
1192 int nr; | |
1193 int tpgrp; | |
1194 unsigned long flags; | |
1195 unsigned long minflt; | |
1196 unsigned long cminflt; | |
1197 unsigned long majflt; | |
1198 unsigned long cmajflt; | |
1199 unsigned long utime; | |
1200 unsigned long stime; | |
1201 long cutime; | |
1202 long cstime; | |
1203 long prio; | |
1204 long nice; | |
1205 long junk; | |
1206 long it_real; | |
1207 uintptr_t start; | |
1208 uintptr_t vsize; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1209 intptr_t rss; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1210 uintptr_t rsslim; |
0 | 1211 uintptr_t scodes; |
1212 uintptr_t ecode; | |
1213 int i; | |
1214 | |
1215 // Figure what the primordial thread stack base is. Code is inspired | |
1216 // by email from Hans Boehm. /proc/self/stat begins with current pid, | |
1217 // followed by command name surrounded by parentheses, state, etc. | |
1218 char stat[2048]; | |
1219 int statlen; | |
1220 | |
1221 fp = fopen("/proc/self/stat", "r"); | |
1222 if (fp) { | |
1223 statlen = fread(stat, 1, 2047, fp); | |
1224 stat[statlen] = '\0'; | |
1225 fclose(fp); | |
1226 | |
1227 // Skip pid and the command string. Note that we could be dealing with | |
1228 // weird command names, e.g. user could decide to rename java launcher | |
1229 // to "java 1.4.2 :)", then the stat file would look like | |
1230 // 1234 (java 1.4.2 :)) R ... ... | |
1231 // We don't really need to know the command string, just find the last | |
1232 // occurrence of ")" and then start parsing from there. See bug 4726580. | |
1233 char * s = strrchr(stat, ')'); | |
1234 | |
1235 i = 0; | |
1236 if (s) { | |
1237 // Skip blank chars | |
1238 do s++; while (isspace(*s)); | |
1239 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1240 #define _UFM UINTX_FORMAT |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1241 #define _DFM INTX_FORMAT |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1242 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1243 /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1244 /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1245 i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM, |
0 | 1246 &state, /* 3 %c */ |
1247 &ppid, /* 4 %d */ | |
1248 &pgrp, /* 5 %d */ | |
1249 &session, /* 6 %d */ | |
1250 &nr, /* 7 %d */ | |
1251 &tpgrp, /* 8 %d */ | |
1252 &flags, /* 9 %lu */ | |
1253 &minflt, /* 10 %lu */ | |
1254 &cminflt, /* 11 %lu */ | |
1255 &majflt, /* 12 %lu */ | |
1256 &cmajflt, /* 13 %lu */ | |
1257 &utime, /* 14 %lu */ | |
1258 &stime, /* 15 %lu */ | |
1259 &cutime, /* 16 %ld */ | |
1260 &cstime, /* 17 %ld */ | |
1261 &prio, /* 18 %ld */ | |
1262 &nice, /* 19 %ld */ | |
1263 &junk, /* 20 %ld */ | |
1264 &it_real, /* 21 %ld */ | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1265 &start, /* 22 UINTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1266 &vsize, /* 23 UINTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1267 &rss, /* 24 INTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1268 &rsslim, /* 25 UINTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1269 &scodes, /* 26 UINTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1270 &ecode, /* 27 UINTX_FORMAT */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1271 &stack_start); /* 28 UINTX_FORMAT */ |
0 | 1272 } |
1273 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1274 #undef _UFM |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1275 #undef _DFM |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1276 |
0 | 1277 if (i != 28 - 2) { |
1278 assert(false, "Bad conversion from /proc/self/stat"); | |
1279 // product mode - assume we are the initial thread, good luck in the | |
1280 // embedded case. | |
1281 warning("Can't detect initial thread stack location - bad conversion"); | |
1282 stack_start = (uintptr_t) &rlim; | |
1283 } | |
1284 } else { | |
1285 // For some reason we can't open /proc/self/stat (for example, running on | |
1286 // FreeBSD with a Linux emulator, or inside chroot), this should work for | |
1287 // most cases, so don't abort: | |
1288 warning("Can't detect initial thread stack location - no /proc/self/stat"); | |
1289 stack_start = (uintptr_t) &rlim; | |
1290 } | |
1291 } | |
1292 | |
1293 // Now we have a pointer (stack_start) very close to the stack top, the | |
1294 // next thing to do is to figure out the exact location of stack top. We | |
1295 // can find out the virtual memory area that contains stack_start by | |
1296 // reading /proc/self/maps, it should be the last vma in /proc/self/maps, | |
1297 // and its upper limit is the real stack top. (again, this would fail if | |
1298 // running inside chroot, because /proc may not exist.) | |
1299 | |
1300 uintptr_t stack_top; | |
1301 address low, high; | |
1302 if (find_vma((address)stack_start, &low, &high)) { | |
1303 // success, "high" is the true stack top. (ignore "low", because initial | |
1304 // thread stack grows on demand, its real bottom is high - RLIMIT_STACK.) | |
1305 stack_top = (uintptr_t)high; | |
1306 } else { | |
1307 // failed, likely because /proc/self/maps does not exist | |
1308 warning("Can't detect initial thread stack location - find_vma failed"); | |
1309 // best effort: stack_start is normally within a few pages below the real | |
1310 // stack top, use it as stack top, and reduce stack size so we won't put | |
1311 // guard page outside stack. | |
1312 stack_top = stack_start; | |
1313 stack_size -= 16 * page_size(); | |
1314 } | |
1315 | |
1316 // stack_top could be partially down the page so align it | |
1317 stack_top = align_size_up(stack_top, page_size()); | |
1318 | |
1319 if (max_size && stack_size > max_size) { | |
1320 _initial_thread_stack_size = max_size; | |
1321 } else { | |
1322 _initial_thread_stack_size = stack_size; | |
1323 } | |
1324 | |
1325 _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size()); | |
1326 _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size; | |
1327 } | |
1328 | |
1329 //////////////////////////////////////////////////////////////////////////////// | |
1330 // time support | |
1331 | |
1332 // Time since start-up in seconds to a fine granularity. | |
1333 // Used by VMSelfDestructTimer and the MemProfiler. | |
1334 double os::elapsedTime() { | |
1335 | |
1336 return (double)(os::elapsed_counter()) * 0.000001; | |
1337 } | |
1338 | |
1339 jlong os::elapsed_counter() { | |
1340 timeval time; | |
1341 int status = gettimeofday(&time, NULL); | |
1342 return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count; | |
1343 } | |
1344 | |
1345 jlong os::elapsed_frequency() { | |
1346 return (1000 * 1000); | |
1347 } | |
1348 | |
10372
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
1349 bool os::supports_vtime() { return true; } |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1350 bool os::enable_vtime() { return false; } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1351 bool os::vtime_enabled() { return false; } |
10372
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
1352 |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1353 double os::elapsedVTime() { |
10372
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
1354 struct rusage usage; |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
1355 int retval = getrusage(RUSAGE_THREAD, &usage); |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
1356 if (retval == 0) { |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
1357 return (double) (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) + (double) (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000 * 1000); |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
1358 } else { |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
1359 // better than nothing, but not much |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
1360 return elapsedTime(); |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10208
diff
changeset
|
1361 } |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1362 } |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
141
diff
changeset
|
1363 |
61 | 1364 jlong os::javaTimeMillis() { |
0 | 1365 timeval time; |
1366 int status = gettimeofday(&time, NULL); | |
1367 assert(status != -1, "linux error"); | |
1368 return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000); | |
1369 } | |
1370 | |
1371 #ifndef CLOCK_MONOTONIC | |
1372 #define CLOCK_MONOTONIC (1) | |
1373 #endif | |
1374 | |
1375 void os::Linux::clock_init() { | |
1376 // we do dlopen's in this particular order due to bug in linux | |
1377 // dynamical loader (see 6348968) leading to crash on exit | |
1378 void* handle = dlopen("librt.so.1", RTLD_LAZY); | |
1379 if (handle == NULL) { | |
1380 handle = dlopen("librt.so", RTLD_LAZY); | |
1381 } | |
1382 | |
1383 if (handle) { | |
1384 int (*clock_getres_func)(clockid_t, struct timespec*) = | |
1385 (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres"); | |
1386 int (*clock_gettime_func)(clockid_t, struct timespec*) = | |
1387 (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_gettime"); | |
1388 if (clock_getres_func && clock_gettime_func) { | |
1389 // See if monotonic clock is supported by the kernel. Note that some | |
1390 // early implementations simply return kernel jiffies (updated every | |
1391 // 1/100 or 1/1000 second). It would be bad to use such a low res clock | |
1392 // for nano time (though the monotonic property is still nice to have). | |
1393 // It's fixed in newer kernels, however clock_getres() still returns | |
1394 // 1/HZ. We check if clock_getres() works, but will ignore its reported | |
1395 // resolution for now. Hopefully as people move to new kernels, this | |
1396 // won't be a problem. | |
1397 struct timespec res; | |
1398 struct timespec tp; | |
1399 if (clock_getres_func (CLOCK_MONOTONIC, &res) == 0 && | |
1400 clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) { | |
1401 // yes, monotonic clock is supported | |
1402 _clock_gettime = clock_gettime_func; | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
1403 return; |
0 | 1404 } else { |
1405 // close librt if there is no monotonic clock | |
1406 dlclose(handle); | |
1407 } | |
1408 } | |
1409 } | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
1410 warning("No monotonic clock was available - timed services may " \ |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
1411 "be adversely affected if the time-of-day clock changes"); |
0 | 1412 } |
1413 | |
1414 #ifndef SYS_clock_getres | |
1415 | |
1416 #if defined(IA32) || defined(AMD64) | |
1417 #define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229) | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1418 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y) |
0 | 1419 #else |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1420 #warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time" |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1421 #define sys_clock_getres(x,y) -1 |
0 | 1422 #endif |
1423 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1424 #else |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
1425 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y) |
0 | 1426 #endif |
1427 | |
1428 void os::Linux::fast_thread_clock_init() { | |
1429 if (!UseLinuxPosixThreadCPUClocks) { | |
1430 return; | |
1431 } | |
1432 clockid_t clockid; | |
1433 struct timespec tp; | |
1434 int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) = | |
1435 (int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid"); | |
1436 | |
1437 // Switch to using fast clocks for thread cpu time if | |
1438 // the sys_clock_getres() returns 0 error code. | |
1439 // Note, that some kernels may support the current thread | |
1440 // clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks | |
1441 // returned by the pthread_getcpuclockid(). | |
1442 // If the fast Posix clocks are supported then the sys_clock_getres() | |
1443 // must return at least tp.tv_sec == 0 which means a resolution | |
1444 // better than 1 sec. This is extra check for reliability. | |
1445 | |
1446 if(pthread_getcpuclockid_func && | |
1447 pthread_getcpuclockid_func(_main_thread, &clockid) == 0 && | |
1448 sys_clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) { | |
1449 | |
1450 _supports_fast_thread_cpu_time = true; | |
1451 _pthread_getcpuclockid = pthread_getcpuclockid_func; | |
1452 } | |
1453 } | |
1454 | |
1455 jlong os::javaTimeNanos() { | |
1456 if (Linux::supports_monotonic_clock()) { | |
1457 struct timespec tp; | |
1458 int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp); | |
1459 assert(status == 0, "gettime error"); | |
1460 jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec); | |
1461 return result; | |
1462 } else { | |
1463 timeval time; | |
1464 int status = gettimeofday(&time, NULL); | |
1465 assert(status != -1, "linux error"); | |
1466 jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec); | |
1467 return 1000 * usecs; | |
1468 } | |
1469 } | |
1470 | |
1471 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { | |
1472 if (Linux::supports_monotonic_clock()) { | |
1473 info_ptr->max_value = ALL_64_BITS; | |
1474 | |
1475 // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past | |
1476 info_ptr->may_skip_backward = false; // not subject to resetting or drifting | |
1477 info_ptr->may_skip_forward = false; // not subject to resetting or drifting | |
1478 } else { | |
1479 // gettimeofday - based on time in seconds since the Epoch thus does not wrap | |
1480 info_ptr->max_value = ALL_64_BITS; | |
1481 | |
1482 // gettimeofday is a real time clock so it skips | |
1483 info_ptr->may_skip_backward = true; | |
1484 info_ptr->may_skip_forward = true; | |
1485 } | |
1486 | |
1487 info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time | |
1488 } | |
1489 | |
1490 // Return the real, user, and system times in seconds from an | |
1491 // arbitrary fixed point in the past. | |
1492 bool os::getTimesSecs(double* process_real_time, | |
1493 double* process_user_time, | |
1494 double* process_system_time) { | |
1495 struct tms ticks; | |
1496 clock_t real_ticks = times(&ticks); | |
1497 | |
1498 if (real_ticks == (clock_t) (-1)) { | |
1499 return false; | |
1500 } else { | |
1501 double ticks_per_second = (double) clock_tics_per_sec; | |
1502 *process_user_time = ((double) ticks.tms_utime) / ticks_per_second; | |
1503 *process_system_time = ((double) ticks.tms_stime) / ticks_per_second; | |
1504 *process_real_time = ((double) real_ticks) / ticks_per_second; | |
1505 | |
1506 return true; | |
1507 } | |
1508 } | |
1509 | |
1510 | |
1511 char * os::local_time_string(char *buf, size_t buflen) { | |
1512 struct tm t; | |
1513 time_t long_time; | |
1514 time(&long_time); | |
1515 localtime_r(&long_time, &t); | |
1516 jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d", | |
1517 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, | |
1518 t.tm_hour, t.tm_min, t.tm_sec); | |
1519 return buf; | |
1520 } | |
1521 | |
548
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
516
diff
changeset
|
1522 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) { |
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
516
diff
changeset
|
1523 return localtime_r(clock, res); |
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
516
diff
changeset
|
1524 } |
773234c55e8c
6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents:
516
diff
changeset
|
1525 |
0 | 1526 //////////////////////////////////////////////////////////////////////////////// |
1527 // runtime exit support | |
1528 | |
1529 // Note: os::shutdown() might be called very early during initialization, or | |
1530 // called from signal handler. Before adding something to os::shutdown(), make | |
1531 // sure it is async-safe and can handle partially initialized VM. | |
1532 void os::shutdown() { | |
1533 | |
1534 // allow PerfMemory to attempt cleanup of any persistent resources | |
1535 perfMemory_exit(); | |
1536 | |
1537 // needs to remove object in file system | |
1538 AttachListener::abort(); | |
1539 | |
1540 // flush buffered output, finish log files | |
1541 ostream_abort(); | |
1542 | |
1543 // Check for abort hook | |
1544 abort_hook_t abort_hook = Arguments::abort_hook(); | |
1545 if (abort_hook != NULL) { | |
1546 abort_hook(); | |
1547 } | |
1548 | |
1549 } | |
1550 | |
1551 // Note: os::abort() might be called very early during initialization, or | |
1552 // called from signal handler. Before adding something to os::abort(), make | |
1553 // sure it is async-safe and can handle partially initialized VM. | |
1554 void os::abort(bool dump_core) { | |
1555 os::shutdown(); | |
1556 if (dump_core) { | |
1557 #ifndef PRODUCT | |
1558 fdStream out(defaultStream::output_fd()); | |
1559 out.print_raw("Current thread is "); | |
1560 char buf[16]; | |
1561 jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id()); | |
1562 out.print_raw_cr(buf); | |
1563 out.print_raw_cr("Dumping core ..."); | |
1564 #endif | |
1565 ::abort(); // dump core | |
1566 } | |
1567 | |
1568 ::exit(1); | |
1569 } | |
1570 | |
1571 // Die immediately, no exit hook, no abort hook, no cleanup. | |
1572 void os::die() { | |
1573 // _exit() on LinuxThreads only kills current thread | |
1574 ::abort(); | |
1575 } | |
1576 | |
1577 // unused on linux for now. | |
1578 void os::set_error_file(const char *logfile) {} | |
1579 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1580 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1581 // This method is a copy of JDK's sysGetLastErrorString |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1582 // from src/solaris/hpi/src/system_md.c |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1583 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1584 size_t os::lasterror(char *buf, size_t len) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1585 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1586 if (errno == 0) return 0; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1587 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1588 const char *s = ::strerror(errno); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1589 size_t n = ::strlen(s); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1590 if (n >= len) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1591 n = len - 1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1592 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1593 ::strncpy(buf, s, n); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1594 buf[n] = '\0'; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1595 return n; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1596 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
1597 |
0 | 1598 intx os::current_thread_id() { return (intx)pthread_self(); } |
1599 int os::current_process_id() { | |
1600 | |
1601 // Under the old linux thread library, linux gives each thread | |
1602 // its own process id. Because of this each thread will return | |
1603 // a different pid if this method were to return the result | |
1604 // of getpid(2). Linux provides no api that returns the pid | |
1605 // of the launcher thread for the vm. This implementation | |
1606 // returns a unique pid, the pid of the launcher thread | |
1607 // that starts the vm 'process'. | |
1608 | |
1609 // Under the NPTL, getpid() returns the same pid as the | |
1610 // launcher thread rather than a unique pid per thread. | |
1611 // Use gettid() if you want the old pre NPTL behaviour. | |
1612 | |
1613 // if you are looking for the result of a call to getpid() that | |
1614 // returns a unique pid for the calling thread, then look at the | |
1615 // OSThread::thread_id() method in osThread_linux.hpp file | |
1616 | |
1617 return (int)(_initial_pid ? _initial_pid : getpid()); | |
1618 } | |
1619 | |
1620 // DLL functions | |
1621 | |
1622 const char* os::dll_file_extension() { return ".so"; } | |
1623 | |
2130
34d64ad817f4
7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents:
2033
diff
changeset
|
1624 // This must be hard coded because it's the system's temporary |
34d64ad817f4
7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents:
2033
diff
changeset
|
1625 // directory not the java application's temp directory, ala java.io.tmpdir. |
34d64ad817f4
7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents:
2033
diff
changeset
|
1626 const char* os::get_temp_directory() { return "/tmp"; } |
0 | 1627 |
691 | 1628 static bool file_exists(const char* filename) { |
1629 struct stat statbuf; | |
1630 if (filename == NULL || strlen(filename) == 0) { | |
1631 return false; | |
1632 } | |
1633 return os::stat(filename, &statbuf) == 0; | |
1634 } | |
1635 | |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6825
diff
changeset
|
1636 bool os::dll_build_name(char* buffer, size_t buflen, |
691 | 1637 const char* pname, const char* fname) { |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6825
diff
changeset
|
1638 bool retval = false; |
691 | 1639 // Copied from libhpi |
242 | 1640 const size_t pnamelen = pname ? strlen(pname) : 0; |
1641 | |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6825
diff
changeset
|
1642 // Return error on buffer overflow. |
242 | 1643 if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6825
diff
changeset
|
1644 return retval; |
242 | 1645 } |
1646 | |
1647 if (pnamelen == 0) { | |
691 | 1648 snprintf(buffer, buflen, "lib%s.so", fname); |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6825
diff
changeset
|
1649 retval = true; |
691 | 1650 } else if (strchr(pname, *os::path_separator()) != NULL) { |
1651 int n; | |
1652 char** pelements = split_path(pname, &n); | |
9059
17bf4d428955
8006103: [parfait] Possible null pointer dereference at hotspot/src/os/linux/vm/os_linux.cpp; os_windows.cpp; os_solaris.cpp; os_bsd.cpp
ccheung
parents:
8812
diff
changeset
|
1653 if (pelements == NULL) { |
9062 | 1654 return false; |
9059
17bf4d428955
8006103: [parfait] Possible null pointer dereference at hotspot/src/os/linux/vm/os_linux.cpp; os_windows.cpp; os_solaris.cpp; os_bsd.cpp
ccheung
parents:
8812
diff
changeset
|
1655 } |
691 | 1656 for (int i = 0 ; i < n ; i++) { |
1657 // Really shouldn't be NULL, but check can't hurt | |
1658 if (pelements[i] == NULL || strlen(pelements[i]) == 0) { | |
1659 continue; // skip the empty path values | |
1660 } | |
1661 snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname); | |
1662 if (file_exists(buffer)) { | |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6825
diff
changeset
|
1663 retval = true; |
691 | 1664 break; |
1665 } | |
1666 } | |
1667 // release the storage | |
1668 for (int i = 0 ; i < n ; i++) { | |
1669 if (pelements[i] != NULL) { | |
6197 | 1670 FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal); |
691 | 1671 } |
1672 } | |
1673 if (pelements != NULL) { | |
6197 | 1674 FREE_C_HEAP_ARRAY(char*, pelements, mtInternal); |
691 | 1675 } |
242 | 1676 } else { |
691 | 1677 snprintf(buffer, buflen, "%s/lib%s.so", pname, fname); |
6966
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6825
diff
changeset
|
1678 retval = true; |
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6825
diff
changeset
|
1679 } |
6cb0d32b828b
8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents:
6825
diff
changeset
|
1680 return retval; |
242 | 1681 } |
1682 | |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
1683 // check if addr is inside libjvm.so |
0 | 1684 bool os::address_is_in_vm(address addr) { |
1685 static address libjvm_base_addr; | |
1686 Dl_info dlinfo; | |
1687 | |
1688 if (libjvm_base_addr == NULL) { | |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1689 if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) { |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1690 libjvm_base_addr = (address)dlinfo.dli_fbase; |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1691 } |
0 | 1692 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); |
1693 } | |
1694 | |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1695 if (dladdr((void *)addr, &dlinfo) != 0) { |
0 | 1696 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; |
1697 } | |
1698 | |
1699 return false; | |
1700 } | |
1701 | |
1702 bool os::dll_address_to_function_name(address addr, char *buf, | |
1703 int buflen, int *offset) { | |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1704 // buf is not optional, but offset is optional |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1705 assert(buf != NULL, "sanity check"); |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1706 |
0 | 1707 Dl_info dlinfo; |
1708 | |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1709 if (dladdr((void*)addr, &dlinfo) != 0) { |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1710 // see if we have a matching symbol |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1711 if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) { |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1712 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1713 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1714 } |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1715 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1716 return true; |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1717 } |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1718 // no matching symbol so try for just file info |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1719 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1720 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1721 buf, buflen, offset, dlinfo.dli_fname)) { |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1722 return true; |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1723 } |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1724 } |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1725 } |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1726 |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1727 buf[0] = '\0'; |
2022
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1728 if (offset != NULL) *offset = -1; |
2d4762ec74af
7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents:
1972
diff
changeset
|
1729 return false; |
0 | 1730 } |
1731 | |
1732 struct _address_to_library_name { | |
1733 address addr; // input : memory address | |
1734 size_t buflen; // size of fname | |
1735 char* fname; // output: library name | |
1736 address base; // library base addr | |
1737 }; | |
1738 | |
1739 static int address_to_library_name_callback(struct dl_phdr_info *info, | |
1740 size_t size, void *data) { | |
1741 int i; | |
1742 bool found = false; | |
1743 address libbase = NULL; | |
1744 struct _address_to_library_name * d = (struct _address_to_library_name *)data; | |
1745 | |
1746 // iterate through all loadable segments | |
1747 for (i = 0; i < info->dlpi_phnum; i++) { | |
1748 address segbase = (address)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr); | |
1749 if (info->dlpi_phdr[i].p_type == PT_LOAD) { | |
1750 // base address of a library is the lowest address of its loaded | |
1751 // segments. | |
1752 if (libbase == NULL || libbase > segbase) { | |
1753 libbase = segbase; | |
1754 } | |
1755 // see if 'addr' is within current segment | |
1756 if (segbase <= d->addr && | |
1757 d->addr < segbase + info->dlpi_phdr[i].p_memsz) { | |
1758 found = true; | |
1759 } | |
1760 } | |
1761 } | |
1762 | |
1763 // dlpi_name is NULL or empty if the ELF file is executable, return 0 | |
1764 // so dll_address_to_library_name() can fall through to use dladdr() which | |
1765 // can figure out executable name from argv[0]. | |
1766 if (found && info->dlpi_name && info->dlpi_name[0]) { | |
1767 d->base = libbase; | |
1768 if (d->fname) { | |
1769 jio_snprintf(d->fname, d->buflen, "%s", info->dlpi_name); | |
1770 } | |
1771 return 1; | |
1772 } | |
1773 return 0; | |
1774 } | |
1775 | |
1776 bool os::dll_address_to_library_name(address addr, char* buf, | |
1777 int buflen, int* offset) { | |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1778 // buf is not optional, but offset is optional |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1779 assert(buf != NULL, "sanity check"); |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1780 |
0 | 1781 Dl_info dlinfo; |
1782 struct _address_to_library_name data; | |
1783 | |
1784 // There is a bug in old glibc dladdr() implementation that it could resolve | |
1785 // to wrong library name if the .so file has a base address != NULL. Here | |
1786 // we iterate through the program headers of all loaded libraries to find | |
1787 // out which library 'addr' really belongs to. This workaround can be | |
1788 // removed once the minimum requirement for glibc is moved to 2.3.x. | |
1789 data.addr = addr; | |
1790 data.fname = buf; | |
1791 data.buflen = buflen; | |
1792 data.base = NULL; | |
1793 int rslt = dl_iterate_phdr(address_to_library_name_callback, (void *)&data); | |
1794 | |
1795 if (rslt) { | |
1796 // buf already contains library name | |
1797 if (offset) *offset = addr - data.base; | |
1798 return true; | |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1799 } |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1800 if (dladdr((void*)addr, &dlinfo) != 0) { |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1801 if (dlinfo.dli_fname != NULL) { |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1802 jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1803 } |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1804 if (dlinfo.dli_fbase != NULL && offset != NULL) { |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1805 *offset = addr - (address)dlinfo.dli_fbase; |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1806 } |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1807 return true; |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1808 } |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1809 |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1810 buf[0] = '\0'; |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1811 if (offset) *offset = -1; |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
1812 return false; |
0 | 1813 } |
1814 | |
1815 // Loads .dll/.so and | |
1816 // in case of error it checks if .dll/.so was built for the | |
1817 // same architecture as Hotspot is running on | |
1818 | |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1819 |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1820 // Remember the stack's state. The Linux dynamic linker will change |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1821 // the stack to 'executable' at most once, so we must safepoint only once. |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1822 bool os::Linux::_stack_is_executable = false; |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1823 |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1824 // VM operation that loads a library. This is necessary if stack protection |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1825 // of the Java stacks can be lost during loading the library. If we |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1826 // do not stop the Java threads, they can stack overflow before the stacks |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1827 // are protected again. |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1828 class VM_LinuxDllLoad: public VM_Operation { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1829 private: |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1830 const char *_filename; |
8812
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
1831 char *_ebuf; |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
1832 int _ebuflen; |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1833 void *_lib; |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1834 public: |
8812
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
1835 VM_LinuxDllLoad(const char *fn, char *ebuf, int ebuflen) : |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
1836 _filename(fn), _ebuf(ebuf), _ebuflen(ebuflen), _lib(NULL) {} |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1837 VMOp_Type type() const { return VMOp_LinuxDllLoad; } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1838 void doit() { |
8812
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
1839 _lib = os::Linux::dll_load_in_vmthread(_filename, _ebuf, _ebuflen); |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1840 os::Linux::_stack_is_executable = true; |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1841 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1842 void* loaded_library() { return _lib; } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1843 }; |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1844 |
0 | 1845 void * os::dll_load(const char *filename, char *ebuf, int ebuflen) |
1846 { | |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1847 void * result = NULL; |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1848 bool load_attempted = false; |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1849 |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1850 // Check whether the library to load might change execution rights |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1851 // of the stack. If they are changed, the protection of the stack |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1852 // guard pages will be lost. We need a safepoint to fix this. |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1853 // |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1854 // See Linux man page execstack(8) for more info. |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1855 if (os::uses_stack_guard_pages() && !os::Linux::_stack_is_executable) { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1856 ElfFile ef(filename); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1857 if (!ef.specifies_noexecstack()) { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1858 if (!is_init_completed()) { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1859 os::Linux::_stack_is_executable = true; |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1860 // This is OK - No Java threads have been created yet, and hence no |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1861 // stack guard pages to fix. |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1862 // |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1863 // This should happen only when you are building JDK7 using a very |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1864 // old version of JDK6 (e.g., with JPRT) and running test_gamma. |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1865 // |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1866 // Dynamic loader will make all stacks executable after |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1867 // this function returns, and will not do that again. |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1868 assert(Threads::first() == NULL, "no Java threads should exist yet."); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1869 } else { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1870 warning("You have loaded library %s which might have disabled stack guard. " |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1871 "The VM will try to fix the stack guard now.\n" |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1872 "It's highly recommended that you fix the library with " |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1873 "'execstack -c <libfile>', or link it with '-z noexecstack'.", |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1874 filename); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1875 |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1876 assert(Thread::current()->is_Java_thread(), "must be Java thread"); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1877 JavaThread *jt = JavaThread::current(); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1878 if (jt->thread_state() != _thread_in_native) { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1879 // This happens when a compiler thread tries to load a hsdis-<arch>.so file |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1880 // that requires ExecStack. Cannot enter safe point. Let's give up. |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1881 warning("Unable to fix stack guard. Giving up."); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1882 } else { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1883 if (!LoadExecStackDllInVMThread) { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1884 // This is for the case where the DLL has an static |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1885 // constructor function that executes JNI code. We cannot |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1886 // load such DLLs in the VMThread. |
8812
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
1887 result = os::Linux::dlopen_helper(filename, ebuf, ebuflen); |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1888 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1889 |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1890 ThreadInVMfromNative tiv(jt); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1891 debug_only(VMNativeEntryWrapper vew;) |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1892 |
8812
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
1893 VM_LinuxDllLoad op(filename, ebuf, ebuflen); |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1894 VMThread::execute(&op); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1895 if (LoadExecStackDllInVMThread) { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1896 result = op.loaded_library(); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1897 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1898 load_attempted = true; |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1899 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1900 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1901 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1902 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1903 |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1904 if (!load_attempted) { |
8812
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
1905 result = os::Linux::dlopen_helper(filename, ebuf, ebuflen); |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1906 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
1907 |
0 | 1908 if (result != NULL) { |
1909 // Successful loading | |
1910 return result; | |
1911 } | |
1912 | |
1913 Elf32_Ehdr elf_head; | |
1914 int diag_msg_max_length=ebuflen-strlen(ebuf); | |
1915 char* diag_msg_buf=ebuf+strlen(ebuf); | |
1916 | |
1917 if (diag_msg_max_length==0) { | |
1918 // No more space in ebuf for additional diagnostics message | |
1919 return NULL; | |
1920 } | |
1921 | |
1922 | |
1923 int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK); | |
1924 | |
1925 if (file_descriptor < 0) { | |
1926 // Can't open library, report dlerror() message | |
1927 return NULL; | |
1928 } | |
1929 | |
1930 bool failed_to_read_elf_head= | |
1931 (sizeof(elf_head)!= | |
1932 (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ; | |
1933 | |
1934 ::close(file_descriptor); | |
1935 if (failed_to_read_elf_head) { | |
1936 // file i/o error - report dlerror() msg | |
1937 return NULL; | |
1938 } | |
1939 | |
1940 typedef struct { | |
1941 Elf32_Half code; // Actual value as defined in elf.h | |
1942 Elf32_Half compat_class; // Compatibility of archs at VM's sense | |
1943 char elf_class; // 32 or 64 bit | |
1944 char endianess; // MSB or LSB | |
1945 char* name; // String representation | |
1946 } arch_t; | |
1947 | |
1948 #ifndef EM_486 | |
1949 #define EM_486 6 /* Intel 80486 */ | |
1950 #endif | |
1951 | |
1952 static const arch_t arch_array[]={ | |
1953 {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, | |
1954 {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, | |
1955 {EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"}, | |
1956 {EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"}, | |
1957 {EM_SPARC, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, | |
1958 {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, | |
1959 {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"}, | |
1960 {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"}, | |
1010 | 1961 {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}, |
1962 {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"}, | |
1963 {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"}, | |
1964 {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"}, | |
1965 {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"}, | |
1966 {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"}, | |
1967 {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"}, | |
1968 {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"} | |
0 | 1969 }; |
1970 | |
1971 #if (defined IA32) | |
1972 static Elf32_Half running_arch_code=EM_386; | |
1973 #elif (defined AMD64) | |
1974 static Elf32_Half running_arch_code=EM_X86_64; | |
1975 #elif (defined IA64) | |
1976 static Elf32_Half running_arch_code=EM_IA_64; | |
1977 #elif (defined __sparc) && (defined _LP64) | |
1978 static Elf32_Half running_arch_code=EM_SPARCV9; | |
1979 #elif (defined __sparc) && (!defined _LP64) | |
1980 static Elf32_Half running_arch_code=EM_SPARC; | |
1981 #elif (defined __powerpc64__) | |
1982 static Elf32_Half running_arch_code=EM_PPC64; | |
1983 #elif (defined __powerpc__) | |
1984 static Elf32_Half running_arch_code=EM_PPC; | |
1010 | 1985 #elif (defined ARM) |
1986 static Elf32_Half running_arch_code=EM_ARM; | |
1987 #elif (defined S390) | |
1988 static Elf32_Half running_arch_code=EM_S390; | |
1989 #elif (defined ALPHA) | |
1990 static Elf32_Half running_arch_code=EM_ALPHA; | |
1991 #elif (defined MIPSEL) | |
1992 static Elf32_Half running_arch_code=EM_MIPS_RS3_LE; | |
1993 #elif (defined PARISC) | |
1994 static Elf32_Half running_arch_code=EM_PARISC; | |
1995 #elif (defined MIPS) | |
1996 static Elf32_Half running_arch_code=EM_MIPS; | |
1997 #elif (defined M68K) | |
1998 static Elf32_Half running_arch_code=EM_68K; | |
0 | 1999 #else |
2000 #error Method os::dll_load requires that one of following is defined:\ | |
1010 | 2001 IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K |
0 | 2002 #endif |
2003 | |
2004 // Identify compatability class for VM's architecture and library's architecture | |
2005 // Obtain string descriptions for architectures | |
2006 | |
2007 arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL}; | |
2008 int running_arch_index=-1; | |
2009 | |
2010 for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) { | |
2011 if (running_arch_code == arch_array[i].code) { | |
2012 running_arch_index = i; | |
2013 } | |
2014 if (lib_arch.code == arch_array[i].code) { | |
2015 lib_arch.compat_class = arch_array[i].compat_class; | |
2016 lib_arch.name = arch_array[i].name; | |
2017 } | |
2018 } | |
2019 | |
2020 assert(running_arch_index != -1, | |
2021 "Didn't find running architecture code (running_arch_code) in arch_array"); | |
2022 if (running_arch_index == -1) { | |
2023 // Even though running architecture detection failed | |
2024 // we may still continue with reporting dlerror() message | |
2025 return NULL; | |
2026 } | |
2027 | |
2028 if (lib_arch.endianess != arch_array[running_arch_index].endianess) { | |
2029 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)"); | |
2030 return NULL; | |
2031 } | |
2032 | |
1010 | 2033 #ifndef S390 |
0 | 2034 if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) { |
2035 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)"); | |
2036 return NULL; | |
2037 } | |
1010 | 2038 #endif // !S390 |
0 | 2039 |
2040 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) { | |
2041 if ( lib_arch.name!=NULL ) { | |
2042 ::snprintf(diag_msg_buf, diag_msg_max_length-1, | |
2043 " (Possible cause: can't load %s-bit .so on a %s-bit platform)", | |
2044 lib_arch.name, arch_array[running_arch_index].name); | |
2045 } else { | |
2046 ::snprintf(diag_msg_buf, diag_msg_max_length-1, | |
2047 " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)", | |
2048 lib_arch.code, | |
2049 arch_array[running_arch_index].name); | |
2050 } | |
2051 } | |
2052 | |
2053 return NULL; | |
2054 } | |
2055 | |
8812
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2056 void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) { |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2057 void * result = ::dlopen(filename, RTLD_LAZY); |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2058 if (result == NULL) { |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2059 ::strncpy(ebuf, ::dlerror(), ebuflen - 1); |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2060 ebuf[ebuflen-1] = '\0'; |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2061 } |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2062 return result; |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2063 } |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2064 |
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2065 void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf, int ebuflen) { |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2066 void * result = NULL; |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2067 if (LoadExecStackDllInVMThread) { |
8812
14509df4cd63
8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents:
8711
diff
changeset
|
2068 result = dlopen_helper(filename, ebuf, ebuflen); |
8710
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2069 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2070 |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2071 // Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2072 // library that requires an executable stack, or which does not have this |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2073 // stack attribute set, dlopen changes the stack attribute to executable. The |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2074 // read protection of the guard pages gets lost. |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2075 // |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2076 // Need to check _stack_is_executable again as multiple VM_LinuxDllLoad |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2077 // may have been queued at the same time. |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2078 |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2079 if (!_stack_is_executable) { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2080 JavaThread *jt = Threads::first(); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2081 |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2082 while (jt) { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2083 if (!jt->stack_guard_zone_unused() && // Stack not yet fully initialized |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2084 jt->stack_yellow_zone_enabled()) { // No pending stack overflow exceptions |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2085 if (!os::guard_memory((char *) jt->stack_red_zone_base() - jt->stack_red_zone_size(), |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2086 jt->stack_yellow_zone_size() + jt->stack_red_zone_size())) { |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2087 warning("Attempt to reguard stack yellow zone failed."); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2088 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2089 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2090 jt = jt->next(); |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2091 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2092 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2093 |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2094 return result; |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2095 } |
9058789475af
7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents:
8675
diff
changeset
|
2096 |
242 | 2097 /* |
2098 * glibc-2.0 libdl is not MT safe. If you are building with any glibc, | |
2099 * chances are you might want to run the generated bits against glibc-2.0 | |
2100 * libdl.so, so always use locking for any version of glibc. | |
2101 */ | |
2102 void* os::dll_lookup(void* handle, const char* name) { | |
2103 pthread_mutex_lock(&dl_mutex); | |
2104 void* res = dlsym(handle, name); | |
2105 pthread_mutex_unlock(&dl_mutex); | |
2106 return res; | |
2107 } | |
0 | 2108 |
2109 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2110 static bool _print_ascii_file(const char* filename, outputStream* st) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2111 int fd = ::open(filename, O_RDONLY); |
0 | 2112 if (fd == -1) { |
2113 return false; | |
2114 } | |
2115 | |
2116 char buf[32]; | |
2117 int bytes; | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2118 while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) { |
0 | 2119 st->print_raw(buf, bytes); |
2120 } | |
2121 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2122 ::close(fd); |
0 | 2123 |
2124 return true; | |
2125 } | |
2126 | |
2127 void os::print_dll_info(outputStream *st) { | |
2128 st->print_cr("Dynamic libraries:"); | |
2129 | |
2130 char fname[32]; | |
2131 pid_t pid = os::Linux::gettid(); | |
2132 | |
2133 jio_snprintf(fname, sizeof(fname), "/proc/%d/maps", pid); | |
2134 | |
2135 if (!_print_ascii_file(fname, st)) { | |
2136 st->print("Can not get library information for pid = %d\n", pid); | |
2137 } | |
2138 } | |
2139 | |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2140 void os::print_os_info_brief(outputStream* st) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2141 os::Linux::print_distro_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2142 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2143 os::Posix::print_uname_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2144 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2145 os::Linux::print_libversion_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2146 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2147 } |
0 | 2148 |
2149 void os::print_os_info(outputStream* st) { | |
2150 st->print("OS:"); | |
2151 | |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2152 os::Linux::print_distro_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2153 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2154 os::Posix::print_uname_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2155 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2156 // Print warning if unsafe chroot environment detected |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2157 if (unsafe_chroot_detected) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2158 st->print("WARNING!! "); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2159 st->print_cr(unstable_chroot_error); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2160 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2161 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2162 os::Linux::print_libversion_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2163 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2164 os::Posix::print_rlimit_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2165 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2166 os::Posix::print_load_average(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2167 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2168 os::Linux::print_full_memory_info(st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2169 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2170 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2171 // Try to identify popular distros. |
12212
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2172 // Most Linux distributions have a /etc/XXX-release file, which contains |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2173 // the OS version string. Newer Linux distributions have a /etc/lsb-release |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2174 // file that also contains the OS version string. Some have more than one |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2175 // /etc/XXX-release file (e.g. Mandrake has both /etc/mandrake-release and |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2176 // /etc/redhat-release.), so the order is important. |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2177 // Any Linux that is based on Redhat (i.e. Oracle, Mandrake, Sun JDS...) have |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2178 // their own specific XXX-release file as well as a redhat-release file. |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2179 // Because of this the XXX-release file needs to be searched for before the |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2180 // redhat-release file. |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2181 // Since Red Hat has a lsb-release file that is not very descriptive the |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2182 // search for redhat-release needs to be before lsb-release. |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2183 // Since the lsb-release file is the new standard it needs to be searched |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2184 // before the older style release files. |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2185 // Searching system-release (Red Hat) and os-release (other Linuxes) are a |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2186 // next to last resort. The os-release file is a new standard that contains |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2187 // distribution information and the system-release file seems to be an old |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2188 // standard that has been replaced by the lsb-release and os-release files. |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2189 // Searching for the debian_version file is the last resort. It contains |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2190 // an informative string like "6.0.6" or "wheezy/sid". Because of this |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2191 // "Debian " is printed before the contents of the debian_version file. |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2192 void os::Linux::print_distro_info(outputStream* st) { |
12212
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2193 if (!_print_ascii_file("/etc/oracle-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2194 !_print_ascii_file("/etc/mandriva-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2195 !_print_ascii_file("/etc/mandrake-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2196 !_print_ascii_file("/etc/sun-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2197 !_print_ascii_file("/etc/redhat-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2198 !_print_ascii_file("/etc/lsb-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2199 !_print_ascii_file("/etc/SuSE-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2200 !_print_ascii_file("/etc/turbolinux-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2201 !_print_ascii_file("/etc/gentoo-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2202 !_print_ascii_file("/etc/ltib-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2203 !_print_ascii_file("/etc/angstrom-version", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2204 !_print_ascii_file("/etc/system-release", st) && |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2205 !_print_ascii_file("/etc/os-release", st)) { |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2206 |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2207 if (file_exists("/etc/debian_version")) { |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2208 st->print("Debian "); |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2209 _print_ascii_file("/etc/debian_version", st); |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2210 } else { |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2211 st->print("Linux"); |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2212 } |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2213 } |
4472884d8b37
6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents:
12211
diff
changeset
|
2214 st->cr(); |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2215 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2216 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2217 void os::Linux::print_libversion_info(outputStream* st) { |
0 | 2218 // libc, pthread |
2219 st->print("libc:"); | |
2220 st->print(os::Linux::glibc_version()); st->print(" "); | |
2221 st->print(os::Linux::libpthread_version()); st->print(" "); | |
2222 if (os::Linux::is_LinuxThreads()) { | |
2223 st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed"); | |
2224 } | |
2225 st->cr(); | |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2226 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2227 |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2228 void os::Linux::print_full_memory_info(outputStream* st) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2229 st->print("\n/proc/meminfo:\n"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2230 _print_ascii_file("/proc/meminfo", st); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2231 st->cr(); |
3800
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
3358
diff
changeset
|
2232 } |
bf6481e5f96d
7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents:
3358
diff
changeset
|
2233 |
0 | 2234 void os::print_memory_info(outputStream* st) { |
2235 | |
2236 st->print("Memory:"); | |
2237 st->print(" %dk page", os::vm_page_size()>>10); | |
2238 | |
2239 // values in struct sysinfo are "unsigned long" | |
2240 struct sysinfo si; | |
2241 sysinfo(&si); | |
2242 | |
2243 st->print(", physical " UINT64_FORMAT "k", | |
2244 os::physical_memory() >> 10); | |
2245 st->print("(" UINT64_FORMAT "k free)", | |
2246 os::available_memory() >> 10); | |
2247 st->print(", swap " UINT64_FORMAT "k", | |
2248 ((jlong)si.totalswap * si.mem_unit) >> 10); | |
2249 st->print("(" UINT64_FORMAT "k free)", | |
2250 ((jlong)si.freeswap * si.mem_unit) >> 10); | |
2251 st->cr(); | |
2252 } | |
2253 | |
6080
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2254 void os::pd_print_cpu_info(outputStream* st) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2255 st->print("\n/proc/cpuinfo:\n"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2256 if (!_print_ascii_file("/proc/cpuinfo", st)) { |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2257 st->print(" <Not Available>"); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2258 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2259 st->cr(); |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2260 } |
7432b9db36ff
7165755: OS Information much longer on linux than other platforms
nloodin
parents:
5937
diff
changeset
|
2261 |
0 | 2262 // Taken from /usr/include/bits/siginfo.h Supposed to be architecture specific |
2263 // but they're the same for all the linux arch that we support | |
2264 // and they're the same for solaris but there's no common place to put this. | |
2265 const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR", | |
2266 "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG", | |
2267 "ILL_COPROC", "ILL_BADSTK" }; | |
2268 | |
2269 const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV", | |
2270 "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES", | |
2271 "FPE_FLTINV", "FPE_FLTSUB", "FPE_FLTDEN" }; | |
2272 | |
2273 const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" }; | |
2274 | |
2275 const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" }; | |
2276 | |
2277 void os::print_siginfo(outputStream* st, void* siginfo) { | |
2278 st->print("siginfo:"); | |
2279 | |
2280 const int buflen = 100; | |
2281 char buf[buflen]; | |
2282 siginfo_t *si = (siginfo_t*)siginfo; | |
2283 st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen)); | |
2284 if (si->si_errno != 0 && strerror_r(si->si_errno, buf, buflen) == 0) { | |
2285 st->print("si_errno=%s", buf); | |
2286 } else { | |
2287 st->print("si_errno=%d", si->si_errno); | |
2288 } | |
2289 const int c = si->si_code; | |
2290 assert(c > 0, "unexpected si_code"); | |
2291 switch (si->si_signo) { | |
2292 case SIGILL: | |
2293 st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]); | |
2294 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2295 break; | |
2296 case SIGFPE: | |
2297 st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]); | |
2298 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2299 break; | |
2300 case SIGSEGV: | |
2301 st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]); | |
2302 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2303 break; | |
2304 case SIGBUS: | |
2305 st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]); | |
2306 st->print(", si_addr=" PTR_FORMAT, si->si_addr); | |
2307 break; | |
2308 default: | |
2309 st->print(", si_code=%d", si->si_code); | |
2310 // no si_addr | |
2311 } | |
2312 | |
2313 if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) && | |
2314 UseSharedSpaces) { | |
2315 FileMapInfo* mapinfo = FileMapInfo::current_info(); | |
2316 if (mapinfo->is_in_shared_space(si->si_addr)) { | |
2317 st->print("\n\nError accessing class data sharing archive." \ | |
2318 " Mapped file inaccessible during execution, " \ | |
2319 " possible disk/network problem."); | |
2320 } | |
2321 } | |
2322 st->cr(); | |
2323 } | |
2324 | |
2325 | |
2326 static void print_signal_handler(outputStream* st, int sig, | |
2327 char* buf, size_t buflen); | |
2328 | |
2329 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { | |
2330 st->print_cr("Signal Handlers:"); | |
2331 print_signal_handler(st, SIGSEGV, buf, buflen); | |
2332 print_signal_handler(st, SIGBUS , buf, buflen); | |
2333 print_signal_handler(st, SIGFPE , buf, buflen); | |
2334 print_signal_handler(st, SIGPIPE, buf, buflen); | |
2335 print_signal_handler(st, SIGXFSZ, buf, buflen); | |
2336 print_signal_handler(st, SIGILL , buf, buflen); | |
2337 print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen); | |
2338 print_signal_handler(st, SR_signum, buf, buflen); | |
2339 print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen); | |
2340 print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen); | |
2341 print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen); | |
2342 print_signal_handler(st, BREAK_SIGNAL, buf, buflen); | |
2343 } | |
2344 | |
2345 static char saved_jvm_path[MAXPATHLEN] = {0}; | |
2346 | |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
2347 // Find the full path to the current module, libjvm.so |
1642 | 2348 void os::jvm_path(char *buf, jint buflen) { |
0 | 2349 // Error checking. |
1642 | 2350 if (buflen < MAXPATHLEN) { |
0 | 2351 assert(false, "must use a large-enough buffer"); |
2352 buf[0] = '\0'; | |
2353 return; | |
2354 } | |
2355 // Lazy resolve the path to current module. | |
2356 if (saved_jvm_path[0] != 0) { | |
2357 strcpy(buf, saved_jvm_path); | |
2358 return; | |
2359 } | |
2360 | |
2361 char dli_fname[MAXPATHLEN]; | |
2362 bool ret = dll_address_to_library_name( | |
2363 CAST_FROM_FN_PTR(address, os::jvm_path), | |
2364 dli_fname, sizeof(dli_fname), NULL); | |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
2365 assert(ret, "cannot locate libjvm"); |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
2366 char *rp = NULL; |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
2367 if (ret && dli_fname[0] != '\0') { |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
2368 rp = realpath(dli_fname, buf); |
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
2369 } |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2370 if (rp == NULL) |
513
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
477
diff
changeset
|
2371 return; |
0 | 2372 |
2302
da091bb67459
7022037: Pause when exiting if debugger is attached on windows
sla
parents:
2204
diff
changeset
|
2373 if (Arguments::created_by_gamma_launcher()) { |
0 | 2374 // Support for the gamma launcher. Typical value for buf is |
2375 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at | |
2376 // the right place in the string, then assume we are installed in a JDK and | |
2377 // we're done. Otherwise, check for a JAVA_HOME environment variable and fix | |
2378 // up the path so it looks like libjvm.so is installed there (append a | |
2379 // fake suffix hotspot/libjvm.so). | |
2380 const char *p = buf + strlen(buf) - 1; | |
2381 for (int count = 0; p > buf && count < 5; ++count) { | |
2382 for (--p; p > buf && *p != '/'; --p) | |
2383 /* empty */ ; | |
2384 } | |
2385 | |
2386 if (strncmp(p, "/jre/lib/", 9) != 0) { | |
2387 // Look for JAVA_HOME in the environment. | |
2388 char* java_home_var = ::getenv("JAVA_HOME"); | |
2389 if (java_home_var != NULL && java_home_var[0] != 0) { | |
1642 | 2390 char* jrelib_p; |
2391 int len; | |
2392 | |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
2393 // Check the current module name "libjvm.so". |
0 | 2394 p = strrchr(buf, '/'); |
2395 assert(strstr(p, "/libjvm") == p, "invalid library name"); | |
2396 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2397 rp = realpath(java_home_var, buf); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2398 if (rp == NULL) |
513
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
477
diff
changeset
|
2399 return; |
1642 | 2400 |
2401 // determine if this is a legacy image or modules image | |
2402 // modules image doesn't have "jre" subdirectory | |
2403 len = strlen(buf); | |
2404 jrelib_p = buf + len; | |
2405 snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch); | |
2406 if (0 != access(buf, F_OK)) { | |
2407 snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch); | |
2408 } | |
2409 | |
0 | 2410 if (0 == access(buf, F_OK)) { |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
2411 // Use current module name "libjvm.so" |
1642 | 2412 len = strlen(buf); |
7456
7d42f3b08300
8005044: remove crufty '_g' support from HS runtime code
dcubed
parents:
7206
diff
changeset
|
2413 snprintf(buf + len, buflen-len, "/hotspot/libjvm.so"); |
0 | 2414 } else { |
2415 // Go back to path of .so | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2416 rp = realpath(dli_fname, buf); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2417 if (rp == NULL) |
513
2328d1d3f8cf
6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents:
477
diff
changeset
|
2418 return; |
0 | 2419 } |
2420 } | |
2421 } | |
2422 } | |
2423 | |
2424 strcpy(saved_jvm_path, buf); | |
2425 } | |
2426 | |
2427 void os::print_jni_name_prefix_on(outputStream* st, int args_size) { | |
2428 // no prefix required, not even "_" | |
2429 } | |
2430 | |
2431 void os::print_jni_name_suffix_on(outputStream* st, int args_size) { | |
2432 // no suffix required | |
2433 } | |
2434 | |
2435 //////////////////////////////////////////////////////////////////////////////// | |
2436 // sun.misc.Signal support | |
2437 | |
2438 static volatile jint sigint_count = 0; | |
2439 | |
2440 static void | |
2441 UserHandler(int sig, void *siginfo, void *context) { | |
2442 // 4511530 - sem_post is serialized and handled by the manager thread. When | |
2443 // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We | |
2444 // don't want to flood the manager thread with sem_post requests. | |
2445 if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1) | |
2446 return; | |
2447 | |
2448 // Ctrl-C is pressed during error reporting, likely because the error | |
2449 // handler fails to abort. Let VM die immediately. | |
2450 if (sig == SIGINT && is_error_reported()) { | |
2451 os::die(); | |
2452 } | |
2453 | |
2454 os::signal_notify(sig); | |
2455 } | |
2456 | |
2457 void* os::user_handler() { | |
2458 return CAST_FROM_FN_PTR(void*, UserHandler); | |
2459 } | |
2460 | |
10405 | 2461 class Semaphore : public StackObj { |
2462 public: | |
2463 Semaphore(); | |
2464 ~Semaphore(); | |
2465 void signal(); | |
2466 void wait(); | |
2467 bool trywait(); | |
2468 bool timedwait(unsigned int sec, int nsec); | |
2469 private: | |
2470 sem_t _semaphore; | |
2471 }; | |
2472 | |
2473 | |
2474 Semaphore::Semaphore() { | |
2475 sem_init(&_semaphore, 0, 0); | |
2476 } | |
2477 | |
2478 Semaphore::~Semaphore() { | |
2479 sem_destroy(&_semaphore); | |
2480 } | |
2481 | |
2482 void Semaphore::signal() { | |
2483 sem_post(&_semaphore); | |
2484 } | |
2485 | |
2486 void Semaphore::wait() { | |
2487 sem_wait(&_semaphore); | |
2488 } | |
2489 | |
2490 bool Semaphore::trywait() { | |
2491 return sem_trywait(&_semaphore) == 0; | |
2492 } | |
2493 | |
2494 bool Semaphore::timedwait(unsigned int sec, int nsec) { | |
2495 struct timespec ts; | |
2496 unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); | |
2497 | |
2498 while (1) { | |
2499 int result = sem_timedwait(&_semaphore, &ts); | |
2500 if (result == 0) { | |
2501 return true; | |
2502 } else if (errno == EINTR) { | |
2503 continue; | |
2504 } else if (errno == ETIMEDOUT) { | |
2505 return false; | |
2506 } else { | |
2507 return false; | |
2508 } | |
2509 } | |
2510 } | |
2511 | |
0 | 2512 extern "C" { |
2513 typedef void (*sa_handler_t)(int); | |
2514 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); | |
2515 } | |
2516 | |
2517 void* os::signal(int signal_number, void* handler) { | |
2518 struct sigaction sigAct, oldSigAct; | |
2519 | |
2520 sigfillset(&(sigAct.sa_mask)); | |
2521 sigAct.sa_flags = SA_RESTART|SA_SIGINFO; | |
2522 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler); | |
2523 | |
2524 if (sigaction(signal_number, &sigAct, &oldSigAct)) { | |
2525 // -1 means registration failed | |
2526 return (void *)-1; | |
2527 } | |
2528 | |
2529 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler); | |
2530 } | |
2531 | |
2532 void os::signal_raise(int signal_number) { | |
2533 ::raise(signal_number); | |
2534 } | |
2535 | |
2536 /* | |
2537 * The following code is moved from os.cpp for making this | |
2538 * code platform specific, which it is by its very nature. | |
2539 */ | |
2540 | |
2541 // Will be modified when max signal is changed to be dynamic | |
2542 int os::sigexitnum_pd() { | |
2543 return NSIG; | |
2544 } | |
2545 | |
2546 // a counter for each possible signal value | |
2547 static volatile jint pending_signals[NSIG+1] = { 0 }; | |
2548 | |
2549 // Linux(POSIX) specific hand shaking semaphore. | |
2550 static sem_t sig_sem; | |
10405 | 2551 static Semaphore sr_semaphore; |
0 | 2552 |
2553 void os::signal_init_pd() { | |
2554 // Initialize signal structures | |
2555 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); | |
2556 | |
2557 // Initialize signal semaphore | |
2558 ::sem_init(&sig_sem, 0, 0); | |
2559 } | |
2560 | |
2561 void os::signal_notify(int sig) { | |
2562 Atomic::inc(&pending_signals[sig]); | |
2563 ::sem_post(&sig_sem); | |
2564 } | |
2565 | |
2566 static int check_pending_signals(bool wait) { | |
2567 Atomic::store(0, &sigint_count); | |
2568 for (;;) { | |
2569 for (int i = 0; i < NSIG + 1; i++) { | |
2570 jint n = pending_signals[i]; | |
2571 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { | |
2572 return i; | |
2573 } | |
2574 } | |
2575 if (!wait) { | |
2576 return -1; | |
2577 } | |
2578 JavaThread *thread = JavaThread::current(); | |
2579 ThreadBlockInVM tbivm(thread); | |
2580 | |
2581 bool threadIsSuspended; | |
2582 do { | |
2583 thread->set_suspend_equivalent(); | |
2584 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() | |
2585 ::sem_wait(&sig_sem); | |
2586 | |
2587 // were we externally suspended while we were waiting? | |
2588 threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); | |
2589 if (threadIsSuspended) { | |
2590 // | |
2591 // The semaphore has been incremented, but while we were waiting | |
2592 // another thread suspended us. We don't want to continue running | |
2593 // while suspended because that would surprise the thread that | |
2594 // suspended us. | |
2595 // | |
2596 ::sem_post(&sig_sem); | |
2597 | |
2598 thread->java_suspend_self(); | |
2599 } | |
2600 } while (threadIsSuspended); | |
2601 } | |
2602 } | |
2603 | |
2604 int os::signal_lookup() { | |
2605 return check_pending_signals(false); | |
2606 } | |
2607 | |
2608 int os::signal_wait() { | |
2609 return check_pending_signals(true); | |
2610 } | |
2611 | |
2612 //////////////////////////////////////////////////////////////////////////////// | |
2613 // Virtual Memory | |
2614 | |
2615 int os::vm_page_size() { | |
2616 // Seems redundant as all get out | |
2617 assert(os::Linux::page_size() != -1, "must call os::init"); | |
2618 return os::Linux::page_size(); | |
2619 } | |
2620 | |
2621 // Solaris allocates memory by pages. | |
2622 int os::vm_allocation_granularity() { | |
2623 assert(os::Linux::page_size() != -1, "must call os::init"); | |
2624 return os::Linux::page_size(); | |
2625 } | |
2626 | |
2627 // Rationale behind this function: | |
2628 // current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable | |
2629 // mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get | |
2630 // samples for JITted code. Here we create private executable mapping over the code cache | |
2631 // and then we can use standard (well, almost, as mapping can change) way to provide | |
2632 // info for the reporting script by storing timestamp and location of symbol | |
2633 void linux_wrap_code(char* base, size_t size) { | |
2634 static volatile jint cnt = 0; | |
2635 | |
2636 if (!UseOprofile) { | |
2637 return; | |
2638 } | |
2639 | |
1497
96d554193f72
6944822: Fix for 6938627 exposes problem with hard-coded buffer sizes
coleenp
parents:
1353
diff
changeset
|
2640 char buf[PATH_MAX+1]; |
0 | 2641 int num = Atomic::add(1, &cnt); |
2642 | |
1353
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
1325
diff
changeset
|
2643 snprintf(buf, sizeof(buf), "%s/hs-vm-%d-%d", |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
1325
diff
changeset
|
2644 os::get_temp_directory(), os::current_process_id(), num); |
0 | 2645 unlink(buf); |
2646 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2647 int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU); |
0 | 2648 |
2649 if (fd != -1) { | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2650 off_t rv = ::lseek(fd, size-2, SEEK_SET); |
0 | 2651 if (rv != (off_t)-1) { |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2652 if (::write(fd, "", 1) == 1) { |
0 | 2653 mmap(base, size, |
2654 PROT_READ|PROT_WRITE|PROT_EXEC, | |
2655 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0); | |
2656 } | |
2657 } | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
2658 ::close(fd); |
0 | 2659 unlink(buf); |
2660 } | |
2661 } | |
2662 | |
10969
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2663 static bool recoverable_mmap_error(int err) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2664 // See if the error is one we can let the caller handle. This |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2665 // list of errno values comes from JBS-6843484. I can't find a |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2666 // Linux man page that documents this specific set of errno |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2667 // values so while this list currently matches Solaris, it may |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2668 // change as we gain experience with this failure mode. |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2669 switch (err) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2670 case EBADF: |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2671 case EINVAL: |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2672 case ENOTSUP: |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2673 // let the caller deal with these errors |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2674 return true; |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2675 |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2676 default: |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2677 // Any remaining errors on this OS can cause our reserved mapping |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2678 // to be lost. That can cause confusion where different data |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2679 // structures think they have the same memory mapped. The worst |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2680 // scenario is if both the VM and a library think they have the |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2681 // same memory mapped. |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2682 return false; |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2683 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2684 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2685 |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2686 static void warn_fail_commit_memory(char* addr, size_t size, bool exec, |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2687 int err) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2688 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2689 ", %d) failed; error='%s' (errno=%d)", addr, size, exec, |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2690 strerror(err), err); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2691 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2692 |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2693 static void warn_fail_commit_memory(char* addr, size_t size, |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2694 size_t alignment_hint, bool exec, |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2695 int err) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2696 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2697 ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, size, |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2698 alignment_hint, exec, strerror(err), err); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2699 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2700 |
0 | 2701 // NOTE: Linux kernel does not really reserve the pages for us. |
2702 // All it does is to check if there are enough free pages | |
2703 // left at the time of mmap(). This could be a potential | |
2704 // problem. | |
10969
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2705 int os::Linux::commit_memory_impl(char* addr, size_t size, bool exec) { |
656 | 2706 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; |
2707 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot, | |
0 | 2708 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); |
3885 | 2709 if (res != (uintptr_t) MAP_FAILED) { |
2710 if (UseNUMAInterleaving) { | |
2711 numa_make_global(addr, size); | |
2712 } | |
10969
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2713 return 0; |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2714 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2715 |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2716 int err = errno; // save errno from mmap() call above |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2717 |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2718 if (!recoverable_mmap_error(err)) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2719 warn_fail_commit_memory(addr, size, exec, err); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2720 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "committing reserved memory."); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2721 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2722 |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2723 return err; |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2724 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2725 |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2726 bool os::pd_commit_memory(char* addr, size_t size, bool exec) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2727 return os::Linux::commit_memory_impl(addr, size, exec) == 0; |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2728 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2729 |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2730 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec, |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2731 const char* mesg) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2732 assert(mesg != NULL, "mesg must be specified"); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2733 int err = os::Linux::commit_memory_impl(addr, size, exec); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2734 if (err != 0) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2735 // the caller wants all commit errors to exit with the specified mesg: |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2736 warn_fail_commit_memory(addr, size, exec, err); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2737 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2738 } |
0 | 2739 } |
2740 | |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2741 // Define MAP_HUGETLB here so we can build HotSpot on old systems. |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2742 #ifndef MAP_HUGETLB |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2743 #define MAP_HUGETLB 0x40000 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2744 #endif |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2745 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2746 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems. |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2747 #ifndef MADV_HUGEPAGE |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2748 #define MADV_HUGEPAGE 14 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2749 #endif |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2750 |
10969
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2751 int os::Linux::commit_memory_impl(char* addr, size_t size, |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2752 size_t alignment_hint, bool exec) { |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
2753 int err = os::Linux::commit_memory_impl(addr, size, exec); |
10969
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2754 if (err == 0) { |
3913
27702f012017
7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents:
3887
diff
changeset
|
2755 realign_memory(addr, size, alignment_hint); |
10969
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2756 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2757 return err; |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2758 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2759 |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2760 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2761 bool exec) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2762 return os::Linux::commit_memory_impl(addr, size, alignment_hint, exec) == 0; |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2763 } |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2764 |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2765 void os::pd_commit_memory_or_exit(char* addr, size_t size, |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2766 size_t alignment_hint, bool exec, |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2767 const char* mesg) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2768 assert(mesg != NULL, "mesg must be specified"); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2769 int err = os::Linux::commit_memory_impl(addr, size, alignment_hint, exec); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2770 if (err != 0) { |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2771 // the caller wants all commit errors to exit with the specified mesg: |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2772 warn_fail_commit_memory(addr, size, alignment_hint, exec, err); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2773 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg); |
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2774 } |
0 | 2775 } |
2776 | |
6197 | 2777 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
2778 if (UseTransparentHugePages && alignment_hint > (size_t)vm_page_size()) { |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2779 // We don't check the return value: madvise(MADV_HUGEPAGE) may not |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2780 // be supported or the memory may already be backed by huge pages. |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2781 ::madvise(addr, bytes, MADV_HUGEPAGE); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2782 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
2783 } |
141 | 2784 |
6197 | 2785 void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { |
5937
cf956638b844
7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents:
5909
diff
changeset
|
2786 // This method works by doing an mmap over an existing mmaping and effectively discarding |
cf956638b844
7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents:
5909
diff
changeset
|
2787 // the existing pages. However it won't work for SHM-based large pages that cannot be |
cf956638b844
7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents:
5909
diff
changeset
|
2788 // uncommitted at all. We don't do anything in this case to avoid creating a segment with |
cf956638b844
7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents:
5909
diff
changeset
|
2789 // small pages on top of the SHM segment. This method always works for small pages, so we |
cf956638b844
7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents:
5909
diff
changeset
|
2790 // allow that in any case. |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
2791 if (alignment_hint <= (size_t)os::vm_page_size() || can_commit_large_page_memory()) { |
10969
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
2792 commit_memory(addr, bytes, alignment_hint, !ExecMem); |
5937
cf956638b844
7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents:
5909
diff
changeset
|
2793 } |
141 | 2794 } |
2795 | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2796 void os::numa_make_global(char *addr, size_t bytes) { |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2797 Linux::numa_interleave_memory(addr, bytes); |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2798 } |
141 | 2799 |
12176
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2800 // Define for numa_set_bind_policy(int). Setting the argument to 0 will set the |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2801 // bind policy to MPOL_PREFERRED for the current thread. |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2802 #define USE_MPOL_PREFERRED 0 |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2803 |
141 | 2804 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { |
12176
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2805 // To make NUMA and large pages more robust when both enabled, we need to ease |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2806 // the requirements on where the memory should be allocated. MPOL_BIND is the |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2807 // default policy and it will force memory to be allocated on the specified |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2808 // node. Changing this to MPOL_PREFERRED will prefer to allocate the memory on |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2809 // the specified node, but will not force it. Using this policy will prevent |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2810 // getting SIGBUS when trying to allocate large pages on NUMA nodes with no |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2811 // free large pages. |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2812 Linux::numa_set_bind_policy(USE_MPOL_PREFERRED); |
141 | 2813 Linux::numa_tonode_memory(addr, bytes, lgrp_hint); |
2814 } | |
2815 | |
2816 bool os::numa_topology_changed() { return false; } | |
2817 | |
2818 size_t os::numa_get_groups_num() { | |
2819 int max_node = Linux::numa_max_node(); | |
2820 return max_node > 0 ? max_node + 1 : 1; | |
2821 } | |
2822 | |
2823 int os::numa_get_group_id() { | |
2824 int cpu_id = Linux::sched_getcpu(); | |
2825 if (cpu_id != -1) { | |
2826 int lgrp_id = Linux::get_node_by_cpu(cpu_id); | |
2827 if (lgrp_id != -1) { | |
2828 return lgrp_id; | |
2829 } | |
0 | 2830 } |
2831 return 0; | |
2832 } | |
2833 | |
141 | 2834 size_t os::numa_get_leaf_groups(int *ids, size_t size) { |
2835 for (size_t i = 0; i < size; i++) { | |
2836 ids[i] = i; | |
2837 } | |
2838 return size; | |
2839 } | |
2840 | |
0 | 2841 bool os::get_page_info(char *start, page_info* info) { |
2842 return false; | |
2843 } | |
2844 | |
2845 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { | |
2846 return end; | |
2847 } | |
2848 | |
3826 | 2849 |
2850 int os::Linux::sched_getcpu_syscall(void) { | |
2851 unsigned int cpu; | |
2852 int retval = -1; | |
2853 | |
2854 #if defined(IA32) | |
3887
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2855 # ifndef SYS_getcpu |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2856 # define SYS_getcpu 318 |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2857 # endif |
3826 | 2858 retval = syscall(SYS_getcpu, &cpu, NULL, NULL); |
2859 #elif defined(AMD64) | |
3887
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2860 // Unfortunately we have to bring all these macros here from vsyscall.h |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2861 // to be able to compile on old linuxes. |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2862 # define __NR_vgetcpu 2 |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2863 # define VSYSCALL_START (-10UL << 20) |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2864 # define VSYSCALL_SIZE 1024 |
9447b2fb6fcf
7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents:
3885
diff
changeset
|
2865 # define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr)) |
3826 | 2866 typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache); |
2867 vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu); | |
2868 retval = vgetcpu(&cpu, NULL, NULL); | |
2869 #endif | |
2870 | |
2871 return (retval == -1) ? retval : cpu; | |
2872 } | |
2873 | |
2191 | 2874 // Something to do with the numa-aware allocator needs these symbols |
2875 extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { } | |
2876 extern "C" JNIEXPORT void numa_error(char *where) { } | |
2877 extern "C" JNIEXPORT int fork1() { return fork(); } | |
141 | 2878 |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2879 |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2880 // If we are running with libnuma version > 2, then we should |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2881 // be trying to use symbols with versions 1.1 |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2882 // If we are running with earlier version, which did not have symbol versions, |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2883 // we should use the base version. |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2884 void* os::Linux::libnuma_dlsym(void* handle, const char *name) { |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2885 void *f = dlvsym(handle, name, "libnuma_1.1"); |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2886 if (f == NULL) { |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2887 f = dlsym(handle, name); |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2888 } |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2889 return f; |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2890 } |
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2891 |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2892 bool os::Linux::libnuma_init() { |
141 | 2893 // sched_getcpu() should be in libc. |
2894 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, | |
2895 dlsym(RTLD_DEFAULT, "sched_getcpu"))); | |
2896 | |
3826 | 2897 // If it's not, try a direct syscall. |
2898 if (sched_getcpu() == -1) | |
2899 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, (void*)&sched_getcpu_syscall)); | |
2900 | |
141 | 2901 if (sched_getcpu() != -1) { // Does it work? |
267
9d6a3a6891f8
6720130: NUMA allocator: The linux version should search for libnuma.so.1
iveresov
parents:
199
diff
changeset
|
2902 void *handle = dlopen("libnuma.so.1", RTLD_LAZY); |
141 | 2903 if (handle != NULL) { |
2904 set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t, | |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2905 libnuma_dlsym(handle, "numa_node_to_cpus"))); |
141 | 2906 set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t, |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2907 libnuma_dlsym(handle, "numa_max_node"))); |
141 | 2908 set_numa_available(CAST_TO_FN_PTR(numa_available_func_t, |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2909 libnuma_dlsym(handle, "numa_available"))); |
141 | 2910 set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t, |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2911 libnuma_dlsym(handle, "numa_tonode_memory"))); |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2912 set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t, |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2913 libnuma_dlsym(handle, "numa_interleave_memory"))); |
12176
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2914 set_numa_set_bind_policy(CAST_TO_FN_PTR(numa_set_bind_policy_func_t, |
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2915 libnuma_dlsym(handle, "numa_set_bind_policy"))); |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2916 |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2917 |
141 | 2918 if (numa_available() != -1) { |
763
cf71f149d7ae
6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents:
761
diff
changeset
|
2919 set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes")); |
141 | 2920 // Create a cpu -> node mapping |
6197 | 2921 _cpu_to_node = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int>(0, true); |
141 | 2922 rebuild_cpu_to_node_map(); |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2923 return true; |
141 | 2924 } |
2925 } | |
2926 } | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2927 return false; |
141 | 2928 } |
2929 | |
2930 // rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id. | |
2931 // The table is later used in get_node_by_cpu(). | |
2932 void os::Linux::rebuild_cpu_to_node_map() { | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2933 const size_t NCPUS = 32768; // Since the buffer size computation is very obscure |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2934 // in libnuma (possible values are starting from 16, |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2935 // and continuing up with every other power of 2, but less |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2936 // than the maximum number of CPUs supported by kernel), and |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2937 // is a subject to change (in libnuma version 2 the requirements |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2938 // are more reasonable) we'll just hardcode the number they use |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2939 // in the library. |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2940 const size_t BitsPerCLong = sizeof(long) * CHAR_BIT; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2941 |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2942 size_t cpu_num = os::active_processor_count(); |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2943 size_t cpu_map_size = NCPUS / BitsPerCLong; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2944 size_t cpu_map_valid_size = |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2945 MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size); |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2946 |
141 | 2947 cpu_to_node()->clear(); |
2948 cpu_to_node()->at_grow(cpu_num - 1); | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2949 size_t node_num = numa_get_groups_num(); |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2950 |
6197 | 2951 unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size, mtInternal); |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2952 for (size_t i = 0; i < node_num; i++) { |
141 | 2953 if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) { |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2954 for (size_t j = 0; j < cpu_map_valid_size; j++) { |
141 | 2955 if (cpu_map[j] != 0) { |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2956 for (size_t k = 0; k < BitsPerCLong; k++) { |
141 | 2957 if (cpu_map[j] & (1UL << k)) { |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2958 cpu_to_node()->at_put(j * BitsPerCLong + k, i); |
141 | 2959 } |
2960 } | |
2961 } | |
2962 } | |
2963 } | |
2964 } | |
6197 | 2965 FREE_C_HEAP_ARRAY(unsigned long, cpu_map, mtInternal); |
141 | 2966 } |
2967 | |
2968 int os::Linux::get_node_by_cpu(int cpu_id) { | |
2969 if (cpu_to_node() != NULL && cpu_id >= 0 && cpu_id < cpu_to_node()->length()) { | |
2970 return cpu_to_node()->at(cpu_id); | |
2971 } | |
2972 return -1; | |
2973 } | |
2974 | |
2975 GrowableArray<int>* os::Linux::_cpu_to_node; | |
2976 os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu; | |
2977 os::Linux::numa_node_to_cpus_func_t os::Linux::_numa_node_to_cpus; | |
2978 os::Linux::numa_max_node_func_t os::Linux::_numa_max_node; | |
2979 os::Linux::numa_available_func_t os::Linux::_numa_available; | |
2980 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory; | |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2981 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory; |
12176
88c255656030
8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents:
11092
diff
changeset
|
2982 os::Linux::numa_set_bind_policy_func_t os::Linux::_numa_set_bind_policy; |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
2983 unsigned long* os::Linux::_numa_all_nodes; |
141 | 2984 |
6197 | 2985 bool os::pd_uncommit_memory(char* addr, size_t size) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2986 uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE, |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2987 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
2988 return res != (uintptr_t) MAP_FAILED; |
0 | 2989 } |
2990 | |
12144
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
2991 static |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
2992 address get_stack_commited_bottom(address bottom, size_t size) { |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
2993 address nbot = bottom; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
2994 address ntop = bottom + size; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
2995 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
2996 size_t page_sz = os::vm_page_size(); |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
2997 unsigned pages = size / page_sz; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
2998 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
2999 unsigned char vec[1]; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3000 unsigned imin = 1, imax = pages + 1, imid; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3001 int mincore_return_value; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3002 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3003 while (imin < imax) { |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3004 imid = (imax + imin) / 2; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3005 nbot = ntop - (imid * page_sz); |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3006 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3007 // Use a trick with mincore to check whether the page is mapped or not. |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3008 // mincore sets vec to 1 if page resides in memory and to 0 if page |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3009 // is swapped output but if page we are asking for is unmapped |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3010 // it returns -1,ENOMEM |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3011 mincore_return_value = mincore(nbot, page_sz, vec); |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3012 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3013 if (mincore_return_value == -1) { |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3014 // Page is not mapped go up |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3015 // to find first mapped page |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3016 if (errno != EAGAIN) { |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3017 assert(errno == ENOMEM, "Unexpected mincore errno"); |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3018 imax = imid; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3019 } |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3020 } else { |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3021 // Page is mapped go down |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3022 // to find first not mapped page |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3023 imin = imid + 1; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3024 } |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3025 } |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3026 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3027 nbot = nbot + page_sz; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3028 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3029 // Adjust stack bottom one page up if last checked page is not mapped |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3030 if (mincore_return_value == -1) { |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3031 nbot = nbot + page_sz; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3032 } |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3033 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3034 return nbot; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3035 } |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3036 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3037 |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3038 // Linux uses a growable mapping for the stack, and if the mapping for |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3039 // the stack guard pages is not removed when we detach a thread the |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3040 // stack cannot grow beyond the pages where the stack guard was |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3041 // mapped. If at some point later in the process the stack expands to |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3042 // that point, the Linux kernel cannot expand the stack any further |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3043 // because the guard pages are in the way, and a segfault occurs. |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3044 // |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3045 // However, it's essential not to split the stack region by unmapping |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3046 // a region (leaving a hole) that's already part of the stack mapping, |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3047 // so if the stack mapping has already grown beyond the guard pages at |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3048 // the time we create them, we have to truncate the stack mapping. |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3049 // So, we need to know the extent of the stack mapping when |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3050 // create_stack_guard_pages() is called. |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3051 |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3052 // We only need this for stacks that are growable: at the time of |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3053 // writing thread stacks don't use growable mappings (i.e. those |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3054 // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3055 // only applies to the main thread. |
2469
677234770800
7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents:
2302
diff
changeset
|
3056 |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3057 // If the (growable) stack mapping already extends beyond the point |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3058 // where we're going to put our guard pages, truncate the mapping at |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3059 // that point by munmap()ping it. This ensures that when we later |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3060 // munmap() the guard pages we don't leave a hole in the stack |
12144
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3061 // mapping. This only affects the main/initial thread |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3062 |
6197 | 3063 bool os::pd_create_stack_guard_pages(char* addr, size_t size) { |
12144
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3064 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3065 if (os::Linux::is_initial_thread()) { |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3066 // As we manually grow stack up to bottom inside create_attached_thread(), |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3067 // it's likely that os::Linux::initial_thread_stack_bottom is mapped and |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3068 // we don't need to do anything special. |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3069 // Check it first, before calling heavy function. |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3070 uintptr_t stack_extent = (uintptr_t) os::Linux::initial_thread_stack_bottom(); |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3071 unsigned char vec[1]; |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3072 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3073 if (mincore((address)stack_extent, os::vm_page_size(), vec) == -1) { |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3074 // Fallback to slow path on all errors, including EAGAIN |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3075 stack_extent = (uintptr_t) get_stack_commited_bottom( |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3076 os::Linux::initial_thread_stack_bottom(), |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3077 (size_t)addr - stack_extent); |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3078 } |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3079 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3080 if (stack_extent < (uintptr_t)addr) { |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3081 ::munmap((void*)stack_extent, (uintptr_t)(addr - stack_extent)); |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3082 } |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3083 } |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3084 |
10969
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
3085 return os::commit_memory(addr, size, !ExecMem); |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3086 } |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3087 |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3088 // If this is a growable mapping, remove the guard pages entirely by |
1750
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
3089 // munmap()ping them. If not, just call uncommit_memory(). This only |
c7004d700b49
6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents:
1681
diff
changeset
|
3090 // affects the main/initial thread, but guard against future OS changes |
12144
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3091 // It's safe to always unmap guard pages for initial thread because we |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3092 // always place it right after end of the mapped region |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3093 |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3094 bool os::remove_stack_guard_pages(char* addr, size_t size) { |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3095 uintptr_t stack_extent, stack_base; |
12144
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3096 |
d8e99408faad
8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents:
12110
diff
changeset
|
3097 if (os::Linux::is_initial_thread()) { |
1320
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3098 return ::munmap(addr, size) == 0; |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3099 } |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3100 |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3101 return os::uncommit_memory(addr, size); |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3102 } |
3b3d12e645e7
6929067: Stack guard pages should be removed when thread is detached
coleenp
parents:
1123
diff
changeset
|
3103 |
0 | 3104 static address _highest_vm_reserved_address = NULL; |
3105 | |
3106 // If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory | |
3107 // at 'requested_addr'. If there are existing memory mappings at the same | |
3108 // location, however, they will be overwritten. If 'fixed' is false, | |
3109 // 'requested_addr' is only treated as a hint, the return value may or | |
3110 // may not start from the requested address. Unlike Linux mmap(), this | |
3111 // function returns NULL to indicate failure. | |
3112 static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) { | |
3113 char * addr; | |
3114 int flags; | |
3115 | |
3116 flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS; | |
3117 if (fixed) { | |
3118 assert((uintptr_t)requested_addr % os::Linux::page_size() == 0, "unaligned address"); | |
3119 flags |= MAP_FIXED; | |
3120 } | |
3121 | |
10157 | 3122 // Map reserved/uncommitted pages PROT_NONE so we fail early if we |
3123 // touch an uncommitted page. Otherwise, the read/write might | |
3124 // succeed if we have enough swap space to back the physical page. | |
3125 addr = (char*)::mmap(requested_addr, bytes, PROT_NONE, | |
0 | 3126 flags, -1, 0); |
3127 | |
3128 if (addr != MAP_FAILED) { | |
3129 // anon_mmap() should only get called during VM initialization, | |
3130 // don't need lock (actually we can skip locking even it can be called | |
3131 // from multiple threads, because _highest_vm_reserved_address is just a | |
3132 // hint about the upper limit of non-stack memory regions.) | |
3133 if ((address)addr + bytes > _highest_vm_reserved_address) { | |
3134 _highest_vm_reserved_address = (address)addr + bytes; | |
3135 } | |
3136 } | |
3137 | |
3138 return addr == MAP_FAILED ? NULL : addr; | |
3139 } | |
3140 | |
3141 // Don't update _highest_vm_reserved_address, because there might be memory | |
3142 // regions above addr + size. If so, releasing a memory region only creates | |
3143 // a hole in the address space, it doesn't help prevent heap-stack collision. | |
3144 // | |
3145 static int anon_munmap(char * addr, size_t size) { | |
3146 return ::munmap(addr, size) == 0; | |
3147 } | |
3148 | |
6197 | 3149 char* os::pd_reserve_memory(size_t bytes, char* requested_addr, |
0 | 3150 size_t alignment_hint) { |
3151 return anon_mmap(requested_addr, bytes, (requested_addr != NULL)); | |
3152 } | |
3153 | |
6197 | 3154 bool os::pd_release_memory(char* addr, size_t size) { |
0 | 3155 return anon_munmap(addr, size); |
3156 } | |
3157 | |
3158 static address highest_vm_reserved_address() { | |
3159 return _highest_vm_reserved_address; | |
3160 } | |
3161 | |
3162 static bool linux_mprotect(char* addr, size_t size, int prot) { | |
3163 // Linux wants the mprotect address argument to be page aligned. | |
3164 char* bottom = (char*)align_size_down((intptr_t)addr, os::Linux::page_size()); | |
3165 | |
3166 // According to SUSv3, mprotect() should only be used with mappings | |
3167 // established by mmap(), and mmap() always maps whole pages. Unaligned | |
3168 // 'addr' likely indicates problem in the VM (e.g. trying to change | |
3169 // protection of malloc'ed or statically allocated memory). Check the | |
3170 // caller if you hit this assert. | |
3171 assert(addr == bottom, "sanity check"); | |
3172 | |
3173 size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Linux::page_size()); | |
3174 return ::mprotect(bottom, size, prot) == 0; | |
3175 } | |
3176 | |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3177 // Set protections specified |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3178 bool os::protect_memory(char* addr, size_t bytes, ProtType prot, |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3179 bool is_committed) { |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3180 unsigned int p = 0; |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3181 switch (prot) { |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3182 case MEM_PROT_NONE: p = PROT_NONE; break; |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3183 case MEM_PROT_READ: p = PROT_READ; break; |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3184 case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break; |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3185 case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break; |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3186 default: |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3187 ShouldNotReachHere(); |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3188 } |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3189 // is_committed is unused. |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
3190 return linux_mprotect(addr, bytes, p); |
0 | 3191 } |
3192 | |
3193 bool os::guard_memory(char* addr, size_t size) { | |
3194 return linux_mprotect(addr, size, PROT_NONE); | |
3195 } | |
3196 | |
3197 bool os::unguard_memory(char* addr, size_t size) { | |
477
24fda36852ce
6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents:
462
diff
changeset
|
3198 return linux_mprotect(addr, size, PROT_READ|PROT_WRITE); |
0 | 3199 } |
3200 | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3201 bool os::Linux::transparent_huge_pages_sanity_check(bool warn, size_t page_size) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3202 bool result = false; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3203 void *p = mmap(NULL, page_size * 2, PROT_READ|PROT_WRITE, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3204 MAP_ANONYMOUS|MAP_PRIVATE, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3205 -1, 0); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3206 if (p != MAP_FAILED) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3207 void *aligned_p = align_ptr_up(p, page_size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3208 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3209 result = madvise(aligned_p, page_size, MADV_HUGEPAGE) == 0; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3210 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3211 munmap(p, page_size * 2); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3212 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3213 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3214 if (warn && !result) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3215 warning("TransparentHugePages is not supported by the operating system."); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3216 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3217 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3218 return result; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3219 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3220 |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3221 bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3222 bool result = false; |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3223 void *p = mmap(NULL, page_size, PROT_READ|PROT_WRITE, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3224 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3225 -1, 0); |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3226 |
10969
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
3227 if (p != MAP_FAILED) { |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3228 // We don't know if this really is a huge page or not. |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3229 FILE *fp = fopen("/proc/self/maps", "r"); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3230 if (fp) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3231 while (!feof(fp)) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3232 char chars[257]; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3233 long x = 0; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3234 if (fgets(chars, sizeof(chars), fp)) { |
3358 | 3235 if (sscanf(chars, "%lx-%*x", &x) == 1 |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3236 && x == (long)p) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3237 if (strstr (chars, "hugepage")) { |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3238 result = true; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3239 break; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3240 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3241 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3242 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3243 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3244 fclose(fp); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3245 } |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3246 munmap(p, page_size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3247 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3248 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3249 if (warn && !result) { |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3250 warning("HugeTLBFS is not supported by the operating system."); |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3251 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3252 |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3253 return result; |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3254 } |
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3255 |
2204
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3256 /* |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3257 * Set the coredump_filter bits to include largepages in core dump (bit 6) |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3258 * |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3259 * From the coredump_filter documentation: |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3260 * |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3261 * - (bit 0) anonymous private memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3262 * - (bit 1) anonymous shared memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3263 * - (bit 2) file-backed private memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3264 * - (bit 3) file-backed shared memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3265 * - (bit 4) ELF header pages in file-backed private memory areas (it is |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3266 * effective only if the bit 2 is cleared) |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3267 * - (bit 5) hugetlb private memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3268 * - (bit 6) hugetlb shared memory |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3269 */ |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3270 static void set_coredump_filter(void) { |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3271 FILE *f; |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3272 long cdm; |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3273 |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3274 if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) { |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3275 return; |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3276 } |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3277 |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3278 if (fscanf(f, "%lx", &cdm) != 1) { |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3279 fclose(f); |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3280 return; |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3281 } |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3282 |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3283 rewind(f); |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3284 |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3285 if ((cdm & LARGEPAGES_BIT) == 0) { |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3286 cdm |= LARGEPAGES_BIT; |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3287 fprintf(f, "%#lx", cdm); |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3288 } |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3289 |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3290 fclose(f); |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3291 } |
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3292 |
0 | 3293 // Large page support |
3294 | |
3295 static size_t _large_page_size = 0; | |
3296 | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3297 size_t os::Linux::find_large_page_size() { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3298 size_t large_page_size = 0; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3299 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3300 // large_page_size on Linux is used to round up heap size. x86 uses either |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3301 // 2M or 4M page, depending on whether PAE (Physical Address Extensions) |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3302 // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3303 // page as large as 256M. |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3304 // |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3305 // Here we try to figure out page size by parsing /proc/meminfo and looking |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3306 // for a line with the following format: |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3307 // Hugepagesize: 2048 kB |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3308 // |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3309 // If we can't determine the value (e.g. /proc is not mounted, or the text |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3310 // format has been changed), we'll use the largest page size supported by |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3311 // the processor. |
0 | 3312 |
1010 | 3313 #ifndef ZERO |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3314 large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M) |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3315 ARM_ONLY(2 * M) PPC_ONLY(4 * M); |
1010 | 3316 #endif // ZERO |
0 | 3317 |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3318 FILE *fp = fopen("/proc/meminfo", "r"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3319 if (fp) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3320 while (!feof(fp)) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3321 int x = 0; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3322 char buf[16]; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3323 if (fscanf(fp, "Hugepagesize: %d", &x) == 1) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3324 if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3325 large_page_size = x * K; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3326 break; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3327 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3328 } else { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3329 // skip to next line |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3330 for (;;) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3331 int ch = fgetc(fp); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3332 if (ch == EOF || ch == (int)'\n') break; |
0 | 3333 } |
3334 } | |
3335 } | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3336 fclose(fp); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3337 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3338 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3339 if (!FLAG_IS_DEFAULT(LargePageSizeInBytes) && LargePageSizeInBytes != large_page_size) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3340 warning("Setting LargePageSizeInBytes has no effect on this OS. Large page size is " |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3341 SIZE_FORMAT "%s.", byte_size_in_proper_unit(large_page_size), |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3342 proper_unit_for_byte_size(large_page_size)); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3343 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3344 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3345 return large_page_size; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3346 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3347 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3348 size_t os::Linux::setup_large_page_size() { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3349 _large_page_size = Linux::find_large_page_size(); |
0 | 3350 const size_t default_page_size = (size_t)Linux::page_size(); |
3351 if (_large_page_size > default_page_size) { | |
3352 _page_sizes[0] = _large_page_size; | |
3353 _page_sizes[1] = default_page_size; | |
3354 _page_sizes[2] = 0; | |
3355 } | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3356 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3357 return _large_page_size; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3358 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3359 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3360 bool os::Linux::setup_large_page_type(size_t page_size) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3361 if (FLAG_IS_DEFAULT(UseHugeTLBFS) && |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3362 FLAG_IS_DEFAULT(UseSHM) && |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3363 FLAG_IS_DEFAULT(UseTransparentHugePages)) { |
12832
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3364 |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3365 // The type of large pages has not been specified by the user. |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3366 |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3367 // Try UseHugeTLBFS and then UseSHM. |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3368 UseHugeTLBFS = UseSHM = true; |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3369 |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3370 // Don't try UseTransparentHugePages since there are known |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3371 // performance issues with it turned on. This might change in the future. |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3372 UseTransparentHugePages = false; |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3373 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3374 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3375 if (UseTransparentHugePages) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3376 bool warn_on_failure = !FLAG_IS_DEFAULT(UseTransparentHugePages); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3377 if (transparent_huge_pages_sanity_check(warn_on_failure, page_size)) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3378 UseHugeTLBFS = false; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3379 UseSHM = false; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3380 return true; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3381 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3382 UseTransparentHugePages = false; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3383 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3384 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3385 if (UseHugeTLBFS) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3386 bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3387 if (hugetlbfs_sanity_check(warn_on_failure, page_size)) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3388 UseSHM = false; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3389 return true; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3390 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3391 UseHugeTLBFS = false; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3392 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3393 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3394 return UseSHM; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3395 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3396 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3397 void os::large_page_init() { |
12832
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3398 if (!UseLargePages && |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3399 !UseTransparentHugePages && |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3400 !UseHugeTLBFS && |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3401 !UseSHM) { |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3402 // Not using large pages. |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3403 return; |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3404 } |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3405 |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3406 if (!FLAG_IS_DEFAULT(UseLargePages) && !UseLargePages) { |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3407 // The user explicitly turned off large pages. |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3408 // Ignore the rest of the large pages flags. |
263f2c796d6c
8024838: Significant slowdown due to transparent huge pages
stefank
parents:
12252
diff
changeset
|
3409 UseTransparentHugePages = false; |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3410 UseHugeTLBFS = false; |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3411 UseSHM = false; |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3412 return; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3413 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3414 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3415 size_t large_page_size = Linux::setup_large_page_size(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3416 UseLargePages = Linux::setup_large_page_type(large_page_size); |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3417 |
2204
63d374c54045
7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents:
2193
diff
changeset
|
3418 set_coredump_filter(); |
0 | 3419 } |
3420 | |
3421 #ifndef SHM_HUGETLB | |
3422 #define SHM_HUGETLB 04000 | |
3423 #endif | |
3424 | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3425 char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec) { |
656 | 3426 // "exec" is passed in but not used. Creating the shared image for |
3427 // the code cache doesn't have an SHM_X executable permission to check. | |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3428 assert(UseLargePages && UseSHM, "only for SHM large pages"); |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3429 assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3430 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3431 if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3432 return NULL; // Fallback to small pages. |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3433 } |
0 | 3434 |
3435 key_t key = IPC_PRIVATE; | |
3436 char *addr; | |
3437 | |
3438 bool warn_on_failure = UseLargePages && | |
3439 (!FLAG_IS_DEFAULT(UseLargePages) || | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3440 !FLAG_IS_DEFAULT(UseSHM) || |
0 | 3441 !FLAG_IS_DEFAULT(LargePageSizeInBytes) |
3442 ); | |
3443 char msg[128]; | |
3444 | |
3445 // Create a large shared memory region to attach to based on size. | |
3446 // Currently, size is the total size of the heap | |
3447 int shmid = shmget(key, bytes, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W); | |
3448 if (shmid == -1) { | |
3449 // Possible reasons for shmget failure: | |
3450 // 1. shmmax is too small for Java heap. | |
3451 // > check shmmax value: cat /proc/sys/kernel/shmmax | |
3452 // > increase shmmax value: echo "0xffffffff" > /proc/sys/kernel/shmmax | |
3453 // 2. not enough large page memory. | |
3454 // > check available large pages: cat /proc/meminfo | |
3455 // > increase amount of large pages: | |
3456 // echo new_value > /proc/sys/vm/nr_hugepages | |
3457 // Note 1: different Linux may use different name for this property, | |
3458 // e.g. on Redhat AS-3 it is "hugetlb_pool". | |
3459 // Note 2: it's possible there's enough physical memory available but | |
3460 // they are so fragmented after a long run that they can't | |
3461 // coalesce into large pages. Try to reserve large pages when | |
3462 // the system is still "fresh". | |
3463 if (warn_on_failure) { | |
3464 jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno); | |
3465 warning(msg); | |
3466 } | |
3467 return NULL; | |
3468 } | |
3469 | |
3470 // attach to the region | |
1537
79bf863697eb
6951686: Using large pages on Linux prevents zero based compressed oops
kvn
parents:
1500
diff
changeset
|
3471 addr = (char*)shmat(shmid, req_addr, 0); |
0 | 3472 int err = errno; |
3473 | |
3474 // Remove shmid. If shmat() is successful, the actual shared memory segment | |
3475 // will be deleted when it's detached by shmdt() or when the process | |
3476 // terminates. If shmat() is not successful this will remove the shared | |
3477 // segment immediately. | |
3478 shmctl(shmid, IPC_RMID, NULL); | |
3479 | |
3480 if ((intptr_t)addr == -1) { | |
3481 if (warn_on_failure) { | |
3482 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); | |
3483 warning(msg); | |
3484 } | |
3485 return NULL; | |
3486 } | |
3487 | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3488 return addr; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3489 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3490 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3491 static void warn_on_large_pages_failure(char* req_addr, size_t bytes, int error) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3492 assert(error == ENOMEM, "Only expect to fail if no memory is available"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3493 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3494 bool warn_on_failure = UseLargePages && |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3495 (!FLAG_IS_DEFAULT(UseLargePages) || |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3496 !FLAG_IS_DEFAULT(UseHugeTLBFS) || |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3497 !FLAG_IS_DEFAULT(LargePageSizeInBytes)); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3498 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3499 if (warn_on_failure) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3500 char msg[128]; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3501 jio_snprintf(msg, sizeof(msg), "Failed to reserve large pages memory req_addr: " |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3502 PTR_FORMAT " bytes: " SIZE_FORMAT " (errno = %d).", req_addr, bytes, error); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3503 warning(msg); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3504 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3505 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3506 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3507 char* os::Linux::reserve_memory_special_huge_tlbfs_only(size_t bytes, char* req_addr, bool exec) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3508 assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3509 assert(is_size_aligned(bytes, os::large_page_size()), "Unaligned size"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3510 assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3511 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3512 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3513 char* addr = (char*)::mmap(req_addr, bytes, prot, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3514 MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3515 -1, 0); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3516 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3517 if (addr == MAP_FAILED) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3518 warn_on_large_pages_failure(req_addr, bytes, errno); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3519 return NULL; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3520 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3521 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3522 assert(is_ptr_aligned(addr, os::large_page_size()), "Must be"); |
8711
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8710
diff
changeset
|
3523 |
0 | 3524 return addr; |
3525 } | |
3526 | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3527 char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t alignment, char* req_addr, bool exec) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3528 size_t large_page_size = os::large_page_size(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3529 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3530 assert(bytes >= large_page_size, "Shouldn't allocate large pages for small sizes"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3531 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3532 // Allocate small pages. |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3533 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3534 char* start; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3535 if (req_addr != NULL) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3536 assert(is_ptr_aligned(req_addr, alignment), "Must be"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3537 assert(is_size_aligned(bytes, alignment), "Must be"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3538 start = os::reserve_memory(bytes, req_addr); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3539 assert(start == NULL || start == req_addr, "Must be"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3540 } else { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3541 start = os::reserve_memory_aligned(bytes, alignment); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3542 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3543 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3544 if (start == NULL) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3545 return NULL; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3546 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3547 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3548 assert(is_ptr_aligned(start, alignment), "Must be"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3549 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3550 // os::reserve_memory_special will record this memory area. |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3551 // Need to release it here to prevent overlapping reservations. |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3552 MemTracker::record_virtual_memory_release((address)start, bytes); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3553 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3554 char* end = start + bytes; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3555 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3556 // Find the regions of the allocated chunk that can be promoted to large pages. |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3557 char* lp_start = (char*)align_ptr_up(start, large_page_size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3558 char* lp_end = (char*)align_ptr_down(end, large_page_size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3559 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3560 size_t lp_bytes = lp_end - lp_start; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3561 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3562 assert(is_size_aligned(lp_bytes, large_page_size), "Must be"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3563 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3564 if (lp_bytes == 0) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3565 // The mapped region doesn't even span the start and the end of a large page. |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3566 // Fall back to allocate a non-special area. |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3567 ::munmap(start, end - start); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3568 return NULL; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3569 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3570 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3571 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3572 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3573 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3574 void* result; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3575 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3576 if (start != lp_start) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3577 result = ::mmap(start, lp_start - start, prot, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3578 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3579 -1, 0); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3580 if (result == MAP_FAILED) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3581 ::munmap(lp_start, end - lp_start); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3582 return NULL; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3583 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3584 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3585 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3586 result = ::mmap(lp_start, lp_bytes, prot, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3587 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_HUGETLB, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3588 -1, 0); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3589 if (result == MAP_FAILED) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3590 warn_on_large_pages_failure(req_addr, bytes, errno); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3591 // If the mmap above fails, the large pages region will be unmapped and we |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3592 // have regions before and after with small pages. Release these regions. |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3593 // |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3594 // | mapped | unmapped | mapped | |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3595 // ^ ^ ^ ^ |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3596 // start lp_start lp_end end |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3597 // |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3598 ::munmap(start, lp_start - start); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3599 ::munmap(lp_end, end - lp_end); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3600 return NULL; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3601 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3602 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3603 if (lp_end != end) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3604 result = ::mmap(lp_end, end - lp_end, prot, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3605 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3606 -1, 0); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3607 if (result == MAP_FAILED) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3608 ::munmap(start, lp_end - start); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3609 return NULL; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3610 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3611 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3612 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3613 return start; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3614 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3615 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3616 char* os::Linux::reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, char* req_addr, bool exec) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3617 assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3618 assert(is_ptr_aligned(req_addr, alignment), "Must be"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3619 assert(is_power_of_2(alignment), "Must be"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3620 assert(is_power_of_2(os::large_page_size()), "Must be"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3621 assert(bytes >= os::large_page_size(), "Shouldn't allocate large pages for small sizes"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3622 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3623 if (is_size_aligned(bytes, os::large_page_size()) && alignment <= os::large_page_size()) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3624 return reserve_memory_special_huge_tlbfs_only(bytes, req_addr, exec); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3625 } else { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3626 return reserve_memory_special_huge_tlbfs_mixed(bytes, alignment, req_addr, exec); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3627 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3628 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3629 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3630 char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3631 assert(UseLargePages, "only for large pages"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3632 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3633 char* addr; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3634 if (UseSHM) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3635 addr = os::Linux::reserve_memory_special_shm(bytes, alignment, req_addr, exec); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3636 } else { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3637 assert(UseHugeTLBFS, "must be"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3638 addr = os::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, req_addr, exec); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3639 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3640 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3641 if (addr != NULL) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3642 if (UseNUMAInterleaving) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3643 numa_make_global(addr, bytes); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3644 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3645 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3646 // The memory is committed |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3647 MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3648 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3649 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3650 return addr; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3651 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3652 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3653 bool os::Linux::release_memory_special_shm(char* base, size_t bytes) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3654 // detaching the SHM segment will also delete it, see reserve_memory_special_shm() |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3655 return shmdt(base) == 0; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3656 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3657 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3658 bool os::Linux::release_memory_special_huge_tlbfs(char* base, size_t bytes) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3659 return pd_release_memory(base, bytes); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3660 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3661 |
0 | 3662 bool os::release_memory_special(char* base, size_t bytes) { |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3663 assert(UseLargePages, "only for large pages"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3664 |
10986
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10969
diff
changeset
|
3665 MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker(); |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3666 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3667 bool res; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3668 if (UseSHM) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3669 res = os::Linux::release_memory_special_shm(base, bytes); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3670 } else { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3671 assert(UseHugeTLBFS, "must be"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3672 res = os::Linux::release_memory_special_huge_tlbfs(base, bytes); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3673 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3674 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3675 if (res) { |
10986
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10969
diff
changeset
|
3676 tkr.record((address)base, bytes); |
8711
6b803ba47588
8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents:
8710
diff
changeset
|
3677 } else { |
10986
1f4355cee9a2
8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents:
10969
diff
changeset
|
3678 tkr.discard(); |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3679 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3680 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3681 return res; |
0 | 3682 } |
3683 | |
3684 size_t os::large_page_size() { | |
3685 return _large_page_size; | |
3686 } | |
3687 | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3688 // With SysV SHM the entire memory region must be allocated as shared |
3286
139667d9836a
7034464: Support transparent large pages on Linux
iveresov
parents:
2302
diff
changeset
|
3689 // memory. |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3690 // HugeTLBFS allows application to commit large page memory on demand. |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3691 // However, when committing memory with HugeTLBFS fails, the region |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3692 // that was supposed to be committed will lose the old reservation |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3693 // and allow other threads to steal that memory region. Because of this |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3694 // behavior we can't commit HugeTLBFS memory. |
0 | 3695 bool os::can_commit_large_page_memory() { |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3696 return UseTransparentHugePages; |
0 | 3697 } |
3698 | |
79
82db0859acbe
6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents:
62
diff
changeset
|
3699 bool os::can_execute_large_page_memory() { |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
3700 return UseTransparentHugePages || UseHugeTLBFS; |
79
82db0859acbe
6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents:
62
diff
changeset
|
3701 } |
82db0859acbe
6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents:
62
diff
changeset
|
3702 |
0 | 3703 // Reserve memory at an arbitrary address, only if that area is |
3704 // available (and not reserved for something else). | |
3705 | |
6197 | 3706 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) { |
0 | 3707 const int max_tries = 10; |
3708 char* base[max_tries]; | |
3709 size_t size[max_tries]; | |
3710 const size_t gap = 0x000000; | |
3711 | |
3712 // Assert only that the size is a multiple of the page size, since | |
3713 // that's all that mmap requires, and since that's all we really know | |
3714 // about at this low abstraction level. If we need higher alignment, | |
3715 // we can either pass an alignment to this method or verify alignment | |
3716 // in one of the methods further up the call chain. See bug 5044738. | |
3717 assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block"); | |
3718 | |
3719 // Repeatedly allocate blocks until the block is allocated at the | |
3720 // right spot. Give up after max_tries. Note that reserve_memory() will | |
3721 // automatically update _highest_vm_reserved_address if the call is | |
3722 // successful. The variable tracks the highest memory address every reserved | |
3723 // by JVM. It is used to detect heap-stack collision if running with | |
3724 // fixed-stack LinuxThreads. Because here we may attempt to reserve more | |
3725 // space than needed, it could confuse the collision detecting code. To | |
3726 // solve the problem, save current _highest_vm_reserved_address and | |
3727 // calculate the correct value before return. | |
3728 address old_highest = _highest_vm_reserved_address; | |
3729 | |
3730 // Linux mmap allows caller to pass an address as hint; give it a try first, | |
3731 // if kernel honors the hint then we can return immediately. | |
3732 char * addr = anon_mmap(requested_addr, bytes, false); | |
3733 if (addr == requested_addr) { | |
3734 return requested_addr; | |
3735 } | |
3736 | |
3737 if (addr != NULL) { | |
3738 // mmap() is successful but it fails to reserve at the requested address | |
3739 anon_munmap(addr, bytes); | |
3740 } | |
3741 | |
3742 int i; | |
3743 for (i = 0; i < max_tries; ++i) { | |
3744 base[i] = reserve_memory(bytes); | |
3745 | |
3746 if (base[i] != NULL) { | |
3747 // Is this the block we wanted? | |
3748 if (base[i] == requested_addr) { | |
3749 size[i] = bytes; | |
3750 break; | |
3751 } | |
3752 | |
3753 // Does this overlap the block we wanted? Give back the overlapped | |
3754 // parts and try again. | |
3755 | |
3756 size_t top_overlap = requested_addr + (bytes + gap) - base[i]; | |
3757 if (top_overlap >= 0 && top_overlap < bytes) { | |
3758 unmap_memory(base[i], top_overlap); | |
3759 base[i] += top_overlap; | |
3760 size[i] = bytes - top_overlap; | |
3761 } else { | |
3762 size_t bottom_overlap = base[i] + bytes - requested_addr; | |
3763 if (bottom_overlap >= 0 && bottom_overlap < bytes) { | |
3764 unmap_memory(requested_addr, bottom_overlap); | |
3765 size[i] = bytes - bottom_overlap; | |
3766 } else { | |
3767 size[i] = bytes; | |
3768 } | |
3769 } | |
3770 } | |
3771 } | |
3772 | |
3773 // Give back the unused reserved pieces. | |
3774 | |
3775 for (int j = 0; j < i; ++j) { | |
3776 if (base[j] != NULL) { | |
3777 unmap_memory(base[j], size[j]); | |
3778 } | |
3779 } | |
3780 | |
3781 if (i < max_tries) { | |
3782 _highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes); | |
3783 return requested_addr; | |
3784 } else { | |
3785 _highest_vm_reserved_address = old_highest; | |
3786 return NULL; | |
3787 } | |
3788 } | |
3789 | |
3790 size_t os::read(int fd, void *buf, unsigned int nBytes) { | |
3791 return ::read(fd, buf, nBytes); | |
3792 } | |
3793 | |
3794 // TODO-FIXME: reconcile Solaris' os::sleep with the linux variation. | |
3795 // Solaris uses poll(), linux uses park(). | |
3796 // Poll() is likely a better choice, assuming that Thread.interrupt() | |
3797 // generates a SIGUSRx signal. Note that SIGUSR1 can interfere with | |
3798 // SIGSEGV, see 4355769. | |
3799 | |
3800 int os::sleep(Thread* thread, jlong millis, bool interruptible) { | |
3801 assert(thread == Thread::current(), "thread consistency check"); | |
3802 | |
3803 ParkEvent * const slp = thread->_SleepEvent ; | |
3804 slp->reset() ; | |
3805 OrderAccess::fence() ; | |
3806 | |
3807 if (interruptible) { | |
3808 jlong prevtime = javaTimeNanos(); | |
3809 | |
3810 for (;;) { | |
3811 if (os::is_interrupted(thread, true)) { | |
3812 return OS_INTRPT; | |
3813 } | |
3814 | |
3815 jlong newtime = javaTimeNanos(); | |
3816 | |
3817 if (newtime - prevtime < 0) { | |
3818 // time moving backwards, should only happen if no monotonic clock | |
3819 // not a guarantee() because JVM should not abort on kernel/glibc bugs | |
3820 assert(!Linux::supports_monotonic_clock(), "time moving backwards"); | |
3821 } else { | |
4712
e7dead7e90af
7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents:
4082
diff
changeset
|
3822 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; |
0 | 3823 } |
3824 | |
3825 if(millis <= 0) { | |
3826 return OS_OK; | |
3827 } | |
3828 | |
3829 prevtime = newtime; | |
3830 | |
3831 { | |
3832 assert(thread->is_Java_thread(), "sanity check"); | |
3833 JavaThread *jt = (JavaThread *) thread; | |
3834 ThreadBlockInVM tbivm(jt); | |
3835 OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */); | |
3836 | |
3837 jt->set_suspend_equivalent(); | |
3838 // cleared by handle_special_suspend_equivalent_condition() or | |
3839 // java_suspend_self() via check_and_wait_while_suspended() | |
3840 | |
3841 slp->park(millis); | |
3842 | |
3843 // were we externally suspended while we were waiting? | |
3844 jt->check_and_wait_while_suspended(); | |
3845 } | |
3846 } | |
3847 } else { | |
3848 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); | |
3849 jlong prevtime = javaTimeNanos(); | |
3850 | |
3851 for (;;) { | |
3852 // It'd be nice to avoid the back-to-back javaTimeNanos() calls on | |
3853 // the 1st iteration ... | |
3854 jlong newtime = javaTimeNanos(); | |
3855 | |
3856 if (newtime - prevtime < 0) { | |
3857 // time moving backwards, should only happen if no monotonic clock | |
3858 // not a guarantee() because JVM should not abort on kernel/glibc bugs | |
3859 assert(!Linux::supports_monotonic_clock(), "time moving backwards"); | |
3860 } else { | |
4712
e7dead7e90af
7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents:
4082
diff
changeset
|
3861 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC; |
0 | 3862 } |
3863 | |
3864 if(millis <= 0) break ; | |
3865 | |
3866 prevtime = newtime; | |
3867 slp->park(millis); | |
3868 } | |
3869 return OS_OK ; | |
3870 } | |
3871 } | |
3872 | |
3873 int os::naked_sleep() { | |
3874 // %% make the sleep time an integer flag. for now use 1 millisec. | |
3875 return os::sleep(Thread::current(), 1, false); | |
3876 } | |
3877 | |
3878 // Sleep forever; naked call to OS-specific sleep; use with CAUTION | |
3879 void os::infinite_sleep() { | |
3880 while (true) { // sleep forever ... | |
3881 ::sleep(100); // ... 100 seconds at a time | |
3882 } | |
3883 } | |
3884 | |
3885 // Used to convert frequent JVM_Yield() to nops | |
3886 bool os::dont_yield() { | |
3887 return DontYieldALot; | |
3888 } | |
3889 | |
3890 void os::yield() { | |
3891 sched_yield(); | |
3892 } | |
3893 | |
3894 os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;} | |
3895 | |
3896 void os::yield_all(int attempts) { | |
3897 // Yields to all threads, including threads with lower priorities | |
3898 // Threads on Linux are all with same priority. The Solaris style | |
3899 // os::yield_all() with nanosleep(1ms) is not necessary. | |
3900 sched_yield(); | |
3901 } | |
3902 | |
3903 // Called from the tight loops to possibly influence time-sharing heuristics | |
3904 void os::loop_breaker(int attempts) { | |
3905 os::yield_all(attempts); | |
3906 } | |
3907 | |
3908 //////////////////////////////////////////////////////////////////////////////// | |
3909 // thread priority support | |
3910 | |
3911 // Note: Normal Linux applications are run with SCHED_OTHER policy. SCHED_OTHER | |
3912 // only supports dynamic priority, static priority must be zero. For real-time | |
3913 // applications, Linux supports SCHED_RR which allows static priority (1-99). | |
3914 // However, for large multi-threaded applications, SCHED_RR is not only slower | |
3915 // than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out | |
3916 // of 5 runs - Sep 2005). | |
3917 // | |
3918 // The following code actually changes the niceness of kernel-thread/LWP. It | |
3919 // has an assumption that setpriority() only modifies one kernel-thread/LWP, | |
3920 // not the entire user process, and user level threads are 1:1 mapped to kernel | |
3921 // threads. It has always been the case, but could change in the future. For | |
3922 // this reason, the code should not be used as default (ThreadPriorityPolicy=0). | |
3923 // It is only used when ThreadPriorityPolicy=1 and requires root privilege. | |
3924 | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3925 int os::java_to_os_priority[CriticalPriority + 1] = { |
0 | 3926 19, // 0 Entry should never be used |
3927 | |
3928 4, // 1 MinPriority | |
3929 3, // 2 | |
3930 2, // 3 | |
3931 | |
3932 1, // 4 | |
3933 0, // 5 NormPriority | |
3934 -1, // 6 | |
3935 | |
3936 -2, // 7 | |
3937 -3, // 8 | |
3938 -4, // 9 NearMaxPriority | |
3939 | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3940 -5, // 10 MaxPriority |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3941 |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3942 -5 // 11 CriticalPriority |
0 | 3943 }; |
3944 | |
3945 static int prio_init() { | |
3946 if (ThreadPriorityPolicy == 1) { | |
3947 // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1 | |
3948 // if effective uid is not root. Perhaps, a more elegant way of doing | |
3949 // this is to test CAP_SYS_NICE capability, but that will require libcap.so | |
3950 if (geteuid() != 0) { | |
3951 if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) { | |
3952 warning("-XX:ThreadPriorityPolicy requires root privilege on Linux"); | |
3953 } | |
3954 ThreadPriorityPolicy = 0; | |
3955 } | |
3956 } | |
4854
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3957 if (UseCriticalJavaThreadPriority) { |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3958 os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority]; |
de268c8a8075
7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents:
4803
diff
changeset
|
3959 } |
0 | 3960 return 0; |
3961 } | |
3962 | |
3963 OSReturn os::set_native_priority(Thread* thread, int newpri) { | |
3964 if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK; | |
3965 | |
3966 int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri); | |
3967 return (ret == 0) ? OS_OK : OS_ERR; | |
3968 } | |
3969 | |
3970 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { | |
3971 if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) { | |
3972 *priority_ptr = java_to_os_priority[NormPriority]; | |
3973 return OS_OK; | |
3974 } | |
3975 | |
3976 errno = 0; | |
3977 *priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id()); | |
3978 return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR); | |
3979 } | |
3980 | |
3981 // Hint to the underlying OS that a task switch would not be good. | |
3982 // Void return because it's a hint and can fail. | |
3983 void os::hint_no_preempt() {} | |
3984 | |
3985 //////////////////////////////////////////////////////////////////////////////// | |
3986 // suspend/resume support | |
3987 | |
3988 // the low-level signal-based suspend/resume support is a remnant from the | |
3989 // old VM-suspension that used to be for java-suspension, safepoints etc, | |
3990 // within hotspot. Now there is a single use-case for this: | |
3991 // - calling get_thread_pc() on the VMThread by the flat-profiler task | |
3992 // that runs in the watcher thread. | |
3993 // The remaining code is greatly simplified from the more general suspension | |
3994 // code that used to be used. | |
3995 // | |
3996 // The protocol is quite simple: | |
3997 // - suspend: | |
3998 // - sends a signal to the target thread | |
3999 // - polls the suspend state of the osthread using a yield loop | |
4000 // - target thread signal handler (SR_handler) sets suspend state | |
4001 // and blocks in sigsuspend until continued | |
4002 // - resume: | |
4003 // - sets target osthread state to continue | |
4004 // - sends signal to end the sigsuspend loop in the SR_handler | |
4005 // | |
4006 // Note that the SR_lock plays no role in this suspend/resume protocol. | |
4007 // | |
4008 | |
4009 static void resume_clear_context(OSThread *osthread) { | |
4010 osthread->set_ucontext(NULL); | |
4011 osthread->set_siginfo(NULL); | |
4012 } | |
4013 | |
4014 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) { | |
4015 osthread->set_ucontext(context); | |
4016 osthread->set_siginfo(siginfo); | |
4017 } | |
4018 | |
4019 // | |
4020 // Handler function invoked when a thread's execution is suspended or | |
4021 // resumed. We have to be careful that only async-safe functions are | |
4022 // called here (Note: most pthread functions are not async safe and | |
4023 // should be avoided.) | |
4024 // | |
4025 // Note: sigwait() is a more natural fit than sigsuspend() from an | |
4026 // interface point of view, but sigwait() prevents the signal hander | |
4027 // from being run. libpthread would get very confused by not having | |
4028 // its signal handlers run and prevents sigwait()'s use with the | |
4029 // mutex granting granting signal. | |
4030 // | |
10405 | 4031 // Currently only ever called on the VMThread and JavaThreads (PC sampling) |
0 | 4032 // |
4033 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) { | |
4034 // Save and restore errno to avoid confusing native code with EINTR | |
4035 // after sigsuspend. | |
4036 int old_errno = errno; | |
4037 | |
4038 Thread* thread = Thread::current(); | |
4039 OSThread* osthread = thread->osthread(); | |
10405 | 4040 assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); |
4041 | |
4042 os::SuspendResume::State current = osthread->sr.state(); | |
4043 if (current == os::SuspendResume::SR_SUSPEND_REQUEST) { | |
0 | 4044 suspend_save_context(osthread, siginfo, context); |
4045 | |
10405 | 4046 // attempt to switch the state, we assume we had a SUSPEND_REQUEST |
4047 os::SuspendResume::State state = osthread->sr.suspended(); | |
4048 if (state == os::SuspendResume::SR_SUSPENDED) { | |
4049 sigset_t suspend_set; // signals for sigsuspend() | |
4050 | |
4051 // get current set of blocked signals and unblock resume signal | |
4052 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set); | |
4053 sigdelset(&suspend_set, SR_signum); | |
4054 | |
4055 sr_semaphore.signal(); | |
4056 // wait here until we are resumed | |
4057 while (1) { | |
4058 sigsuspend(&suspend_set); | |
4059 | |
4060 os::SuspendResume::State result = osthread->sr.running(); | |
4061 if (result == os::SuspendResume::SR_RUNNING) { | |
4062 sr_semaphore.signal(); | |
4063 break; | |
4064 } | |
4065 } | |
4066 | |
4067 } else if (state == os::SuspendResume::SR_RUNNING) { | |
4068 // request was cancelled, continue | |
4069 } else { | |
4070 ShouldNotReachHere(); | |
4071 } | |
0 | 4072 |
4073 resume_clear_context(osthread); | |
10405 | 4074 } else if (current == os::SuspendResume::SR_RUNNING) { |
4075 // request was cancelled, continue | |
4076 } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) { | |
4077 // ignore | |
0 | 4078 } else { |
10405 | 4079 // ignore |
0 | 4080 } |
4081 | |
4082 errno = old_errno; | |
4083 } | |
4084 | |
4085 | |
4086 static int SR_initialize() { | |
4087 struct sigaction act; | |
4088 char *s; | |
4089 /* Get signal number to use for suspend/resume */ | |
4090 if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) { | |
4091 int sig = ::strtol(s, 0, 10); | |
4092 if (sig > 0 || sig < _NSIG) { | |
4093 SR_signum = sig; | |
4094 } | |
4095 } | |
4096 | |
4097 assert(SR_signum > SIGSEGV && SR_signum > SIGBUS, | |
4098 "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769"); | |
4099 | |
4100 sigemptyset(&SR_sigset); | |
4101 sigaddset(&SR_sigset, SR_signum); | |
4102 | |
4103 /* Set up signal handler for suspend/resume */ | |
4104 act.sa_flags = SA_RESTART|SA_SIGINFO; | |
4105 act.sa_handler = (void (*)(int)) SR_handler; | |
4106 | |
4107 // SR_signum is blocked by default. | |
4108 // 4528190 - We also need to block pthread restart signal (32 on all | |
4109 // supported Linux platforms). Note that LinuxThreads need to block | |
4110 // this signal for all threads to work properly. So we don't have | |
4111 // to use hard-coded signal number when setting up the mask. | |
4112 pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask); | |
4113 | |
4114 if (sigaction(SR_signum, &act, 0) == -1) { | |
4115 return -1; | |
4116 } | |
4117 | |
4118 // Save signal flag | |
4119 os::Linux::set_our_sigflags(SR_signum, act.sa_flags); | |
4120 return 0; | |
4121 } | |
4122 | |
10405 | 4123 static int sr_notify(OSThread* osthread) { |
4124 int status = pthread_kill(osthread->pthread_id(), SR_signum); | |
4125 assert_status(status == 0, status, "pthread_kill"); | |
4126 return status; | |
4127 } | |
4128 | |
4129 // "Randomly" selected value for how long we want to spin | |
4130 // before bailing out on suspending a thread, also how often | |
4131 // we send a signal to a thread we want to resume | |
4132 static const int RANDOMLY_LARGE_INTEGER = 1000000; | |
4133 static const int RANDOMLY_LARGE_INTEGER2 = 100; | |
0 | 4134 |
4135 // returns true on success and false on error - really an error is fatal | |
4136 // but this seems the normal response to library errors | |
4137 static bool do_suspend(OSThread* osthread) { | |
10405 | 4138 assert(osthread->sr.is_running(), "thread should be running"); |
4139 assert(!sr_semaphore.trywait(), "semaphore has invalid state"); | |
4140 | |
0 | 4141 // mark as suspended and send signal |
10405 | 4142 if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) { |
4143 // failed to switch, state wasn't running? | |
4144 ShouldNotReachHere(); | |
4145 return false; | |
4146 } | |
4147 | |
4148 if (sr_notify(osthread) != 0) { | |
4149 ShouldNotReachHere(); | |
4150 } | |
4151 | |
4152 // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED | |
4153 while (true) { | |
4154 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { | |
4155 break; | |
4156 } else { | |
4157 // timeout | |
4158 os::SuspendResume::State cancelled = osthread->sr.cancel_suspend(); | |
4159 if (cancelled == os::SuspendResume::SR_RUNNING) { | |
4160 return false; | |
4161 } else if (cancelled == os::SuspendResume::SR_SUSPENDED) { | |
4162 // make sure that we consume the signal on the semaphore as well | |
4163 sr_semaphore.wait(); | |
4164 break; | |
4165 } else { | |
4166 ShouldNotReachHere(); | |
4167 return false; | |
4168 } | |
0 | 4169 } |
10405 | 4170 } |
4171 | |
4172 guarantee(osthread->sr.is_suspended(), "Must be suspended"); | |
4173 return true; | |
0 | 4174 } |
4175 | |
4176 static void do_resume(OSThread* osthread) { | |
4177 assert(osthread->sr.is_suspended(), "thread should be suspended"); | |
10405 | 4178 assert(!sr_semaphore.trywait(), "invalid semaphore state"); |
4179 | |
4180 if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) { | |
4181 // failed to switch to WAKEUP_REQUEST | |
4182 ShouldNotReachHere(); | |
4183 return; | |
4184 } | |
4185 | |
4186 while (true) { | |
4187 if (sr_notify(osthread) == 0) { | |
4188 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { | |
4189 if (osthread->sr.is_running()) { | |
4190 return; | |
4191 } | |
4192 } | |
4193 } else { | |
4194 ShouldNotReachHere(); | |
0 | 4195 } |
4196 } | |
10405 | 4197 |
4198 guarantee(osthread->sr.is_running(), "Must be running!"); | |
0 | 4199 } |
4200 | |
4201 //////////////////////////////////////////////////////////////////////////////// | |
4202 // interrupt support | |
4203 | |
4204 void os::interrupt(Thread* thread) { | |
4205 assert(Thread::current() == thread || Threads_lock->owned_by_self(), | |
4206 "possibility of dangling Thread pointer"); | |
4207 | |
4208 OSThread* osthread = thread->osthread(); | |
4209 | |
4210 if (!osthread->interrupted()) { | |
4211 osthread->set_interrupted(true); | |
4212 // More than one thread can get here with the same value of osthread, | |
4213 // resulting in multiple notifications. We do, however, want the store | |
4214 // to interrupted() to be visible to other threads before we execute unpark(). | |
4215 OrderAccess::fence(); | |
4216 ParkEvent * const slp = thread->_SleepEvent ; | |
4217 if (slp != NULL) slp->unpark() ; | |
4218 } | |
4219 | |
4220 // For JSR166. Unpark even if interrupt status already was set | |
4221 if (thread->is_Java_thread()) | |
4222 ((JavaThread*)thread)->parker()->unpark(); | |
4223 | |
4224 ParkEvent * ev = thread->_ParkEvent ; | |
4225 if (ev != NULL) ev->unpark() ; | |
4226 | |
4227 } | |
4228 | |
4229 bool os::is_interrupted(Thread* thread, bool clear_interrupted) { | |
4230 assert(Thread::current() == thread || Threads_lock->owned_by_self(), | |
4231 "possibility of dangling Thread pointer"); | |
4232 | |
4233 OSThread* osthread = thread->osthread(); | |
4234 | |
4235 bool interrupted = osthread->interrupted(); | |
4236 | |
4237 if (interrupted && clear_interrupted) { | |
4238 osthread->set_interrupted(false); | |
4239 // consider thread->_SleepEvent->reset() ... optional optimization | |
4240 } | |
4241 | |
4242 return interrupted; | |
4243 } | |
4244 | |
4245 /////////////////////////////////////////////////////////////////////////////////// | |
4246 // signal handling (except suspend/resume) | |
4247 | |
4248 // This routine may be used by user applications as a "hook" to catch signals. | |
4249 // The user-defined signal handler must pass unrecognized signals to this | |
4250 // routine, and if it returns true (non-zero), then the signal handler must | |
4251 // return immediately. If the flag "abort_if_unrecognized" is true, then this | |
4252 // routine will never retun false (zero), but instead will execute a VM panic | |
4253 // routine kill the process. | |
4254 // | |
4255 // If this routine returns false, it is OK to call it again. This allows | |
4256 // the user-defined signal handler to perform checks either before or after | |
4257 // the VM performs its own checks. Naturally, the user code would be making | |
4258 // a serious error if it tried to handle an exception (such as a null check | |
4259 // or breakpoint) that the VM was generating for its own correct operation. | |
4260 // | |
4261 // This routine may recognize any of the following kinds of signals: | |
4262 // SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1. | |
4263 // It should be consulted by handlers for any of those signals. | |
4264 // | |
4265 // The caller of this routine must pass in the three arguments supplied | |
4266 // to the function referred to in the "sa_sigaction" (not the "sa_handler") | |
4267 // field of the structure passed to sigaction(). This routine assumes that | |
4268 // the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART. | |
4269 // | |
4270 // Note that the VM will print warnings if it detects conflicting signal | |
4271 // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers". | |
4272 // | |
2191 | 4273 extern "C" JNIEXPORT int |
0 | 4274 JVM_handle_linux_signal(int signo, siginfo_t* siginfo, |
4275 void* ucontext, int abort_if_unrecognized); | |
4276 | |
4277 void signalHandler(int sig, siginfo_t* info, void* uc) { | |
4278 assert(info != NULL && uc != NULL, "it must be old kernel"); | |
8067 | 4279 int orig_errno = errno; // Preserve errno value over signal handler. |
0 | 4280 JVM_handle_linux_signal(sig, info, uc, true); |
8067 | 4281 errno = orig_errno; |
0 | 4282 } |
4283 | |
4284 | |
4285 // This boolean allows users to forward their own non-matching signals | |
4286 // to JVM_handle_linux_signal, harmlessly. | |
4287 bool os::Linux::signal_handlers_are_installed = false; | |
4288 | |
4289 // For signal-chaining | |
4290 struct sigaction os::Linux::sigact[MAXSIGNUM]; | |
4291 unsigned int os::Linux::sigs = 0; | |
4292 bool os::Linux::libjsig_is_loaded = false; | |
4293 typedef struct sigaction *(*get_signal_t)(int); | |
4294 get_signal_t os::Linux::get_signal_action = NULL; | |
4295 | |
4296 struct sigaction* os::Linux::get_chained_signal_action(int sig) { | |
4297 struct sigaction *actp = NULL; | |
4298 | |
4299 if (libjsig_is_loaded) { | |
4300 // Retrieve the old signal handler from libjsig | |
4301 actp = (*get_signal_action)(sig); | |
4302 } | |
4303 if (actp == NULL) { | |
4304 // Retrieve the preinstalled signal handler from jvm | |
4305 actp = get_preinstalled_handler(sig); | |
4306 } | |
4307 | |
4308 return actp; | |
4309 } | |
4310 | |
4311 static bool call_chained_handler(struct sigaction *actp, int sig, | |
4312 siginfo_t *siginfo, void *context) { | |
4313 // Call the old signal handler | |
4314 if (actp->sa_handler == SIG_DFL) { | |
4315 // It's more reasonable to let jvm treat it as an unexpected exception | |
4316 // instead of taking the default action. | |
4317 return false; | |
4318 } else if (actp->sa_handler != SIG_IGN) { | |
4319 if ((actp->sa_flags & SA_NODEFER) == 0) { | |
4320 // automaticlly block the signal | |
4321 sigaddset(&(actp->sa_mask), sig); | |
4322 } | |
4323 | |
4324 sa_handler_t hand; | |
4325 sa_sigaction_t sa; | |
4326 bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0; | |
4327 // retrieve the chained handler | |
4328 if (siginfo_flag_set) { | |
4329 sa = actp->sa_sigaction; | |
4330 } else { | |
4331 hand = actp->sa_handler; | |
4332 } | |
4333 | |
4334 if ((actp->sa_flags & SA_RESETHAND) != 0) { | |
4335 actp->sa_handler = SIG_DFL; | |
4336 } | |
4337 | |
4338 // try to honor the signal mask | |
4339 sigset_t oset; | |
4340 pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset); | |
4341 | |
4342 // call into the chained handler | |
4343 if (siginfo_flag_set) { | |
4344 (*sa)(sig, siginfo, context); | |
4345 } else { | |
4346 (*hand)(sig); | |
4347 } | |
4348 | |
4349 // restore the signal mask | |
4350 pthread_sigmask(SIG_SETMASK, &oset, 0); | |
4351 } | |
4352 // Tell jvm's signal handler the signal is taken care of. | |
4353 return true; | |
4354 } | |
4355 | |
4356 bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) { | |
4357 bool chained = false; | |
4358 // signal-chaining | |
4359 if (UseSignalChaining) { | |
4360 struct sigaction *actp = get_chained_signal_action(sig); | |
4361 if (actp != NULL) { | |
4362 chained = call_chained_handler(actp, sig, siginfo, context); | |
4363 } | |
4364 } | |
4365 return chained; | |
4366 } | |
4367 | |
4368 struct sigaction* os::Linux::get_preinstalled_handler(int sig) { | |
4369 if ((( (unsigned int)1 << sig ) & sigs) != 0) { | |
4370 return &sigact[sig]; | |
4371 } | |
4372 return NULL; | |
4373 } | |
4374 | |
4375 void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) { | |
4376 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
4377 sigact[sig] = oldAct; | |
4378 sigs |= (unsigned int)1 << sig; | |
4379 } | |
4380 | |
4381 // for diagnostic | |
4382 int os::Linux::sigflags[MAXSIGNUM]; | |
4383 | |
4384 int os::Linux::get_our_sigflags(int sig) { | |
4385 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
4386 return sigflags[sig]; | |
4387 } | |
4388 | |
4389 void os::Linux::set_our_sigflags(int sig, int flags) { | |
4390 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
4391 sigflags[sig] = flags; | |
4392 } | |
4393 | |
4394 void os::Linux::set_signal_handler(int sig, bool set_installed) { | |
4395 // Check for overwrite. | |
4396 struct sigaction oldAct; | |
4397 sigaction(sig, (struct sigaction*)NULL, &oldAct); | |
4398 | |
4399 void* oldhand = oldAct.sa_sigaction | |
4400 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) | |
4401 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); | |
4402 if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) && | |
4403 oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) && | |
4404 oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) { | |
4405 if (AllowUserSignalHandlers || !set_installed) { | |
4406 // Do not overwrite; user takes responsibility to forward to us. | |
4407 return; | |
4408 } else if (UseSignalChaining) { | |
4409 // save the old handler in jvm | |
4410 save_preinstalled_handler(sig, oldAct); | |
4411 // libjsig also interposes the sigaction() call below and saves the | |
4412 // old sigaction on it own. | |
4413 } else { | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1353
diff
changeset
|
4414 fatal(err_msg("Encountered unexpected pre-existing sigaction handler " |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1353
diff
changeset
|
4415 "%#lx for signal %d.", (long)oldhand, sig)); |
0 | 4416 } |
4417 } | |
4418 | |
4419 struct sigaction sigAct; | |
4420 sigfillset(&(sigAct.sa_mask)); | |
4421 sigAct.sa_handler = SIG_DFL; | |
4422 if (!set_installed) { | |
4423 sigAct.sa_flags = SA_SIGINFO|SA_RESTART; | |
4424 } else { | |
4425 sigAct.sa_sigaction = signalHandler; | |
4426 sigAct.sa_flags = SA_SIGINFO|SA_RESTART; | |
4427 } | |
4428 // Save flags, which are set by ours | |
4429 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range"); | |
4430 sigflags[sig] = sigAct.sa_flags; | |
4431 | |
4432 int ret = sigaction(sig, &sigAct, &oldAct); | |
4433 assert(ret == 0, "check"); | |
4434 | |
4435 void* oldhand2 = oldAct.sa_sigaction | |
4436 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) | |
4437 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); | |
4438 assert(oldhand2 == oldhand, "no concurrent signal handler installation"); | |
4439 } | |
4440 | |
4441 // install signal handlers for signals that HotSpot needs to | |
4442 // handle in order to support Java-level exception handling. | |
4443 | |
4444 void os::Linux::install_signal_handlers() { | |
4445 if (!signal_handlers_are_installed) { | |
4446 signal_handlers_are_installed = true; | |
4447 | |
4448 // signal-chaining | |
4449 typedef void (*signal_setting_t)(); | |
4450 signal_setting_t begin_signal_setting = NULL; | |
4451 signal_setting_t end_signal_setting = NULL; | |
4452 begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t, | |
4453 dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting")); | |
4454 if (begin_signal_setting != NULL) { | |
4455 end_signal_setting = CAST_TO_FN_PTR(signal_setting_t, | |
4456 dlsym(RTLD_DEFAULT, "JVM_end_signal_setting")); | |
4457 get_signal_action = CAST_TO_FN_PTR(get_signal_t, | |
4458 dlsym(RTLD_DEFAULT, "JVM_get_signal_action")); | |
4459 libjsig_is_loaded = true; | |
4460 assert(UseSignalChaining, "should enable signal-chaining"); | |
4461 } | |
4462 if (libjsig_is_loaded) { | |
4463 // Tell libjsig jvm is setting signal handlers | |
4464 (*begin_signal_setting)(); | |
4465 } | |
4466 | |
4467 set_signal_handler(SIGSEGV, true); | |
4468 set_signal_handler(SIGPIPE, true); | |
4469 set_signal_handler(SIGBUS, true); | |
4470 set_signal_handler(SIGILL, true); | |
4471 set_signal_handler(SIGFPE, true); | |
4472 set_signal_handler(SIGXFSZ, true); | |
4473 | |
4474 if (libjsig_is_loaded) { | |
4475 // Tell libjsig jvm finishes setting signal handlers | |
4476 (*end_signal_setting)(); | |
4477 } | |
4478 | |
4479 // We don't activate signal checker if libjsig is in place, we trust ourselves | |
3956
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
4480 // and if UserSignalHandler is installed all bets are off. |
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
4481 // Log that signal checking is off only if -verbose:jni is specified. |
0 | 4482 if (CheckJNICalls) { |
4483 if (libjsig_is_loaded) { | |
3956
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
4484 if (PrintJNIResolving) { |
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
4485 tty->print_cr("Info: libjsig is activated, all active signal checking is disabled"); |
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
4486 } |
0 | 4487 check_signals = false; |
4488 } | |
4489 if (AllowUserSignalHandlers) { | |
3956
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
4490 if (PrintJNIResolving) { |
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
4491 tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled"); |
3607aac85aa9
7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents:
3913
diff
changeset
|
4492 } |
0 | 4493 check_signals = false; |
4494 } | |
4495 } | |
4496 } | |
4497 } | |
4498 | |
4499 // This is the fastest way to get thread cpu time on Linux. | |
4500 // Returns cpu time (user+sys) for any thread, not only for current. | |
4501 // POSIX compliant clocks are implemented in the kernels 2.6.16+. | |
4502 // It might work on 2.6.10+ with a special kernel/glibc patch. | |
4503 // For reference, please, see IEEE Std 1003.1-2004: | |
4504 // http://www.unix.org/single_unix_specification | |
4505 | |
4506 jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) { | |
4507 struct timespec tp; | |
4508 int rc = os::Linux::clock_gettime(clockid, &tp); | |
4509 assert(rc == 0, "clock_gettime is expected to return 0 code"); | |
4510 | |
4712
e7dead7e90af
7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents:
4082
diff
changeset
|
4511 return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec; |
0 | 4512 } |
4513 | |
4514 ///// | |
4515 // glibc on Linux platform uses non-documented flag | |
4516 // to indicate, that some special sort of signal | |
4517 // trampoline is used. | |
4518 // We will never set this flag, and we should | |
4519 // ignore this flag in our diagnostic | |
4520 #ifdef SIGNIFICANT_SIGNAL_MASK | |
4521 #undef SIGNIFICANT_SIGNAL_MASK | |
4522 #endif | |
4523 #define SIGNIFICANT_SIGNAL_MASK (~0x04000000) | |
4524 | |
4525 static const char* get_signal_handler_name(address handler, | |
4526 char* buf, int buflen) { | |
4527 int offset; | |
4528 bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset); | |
4529 if (found) { | |
4530 // skip directory names | |
4531 const char *p1, *p2; | |
4532 p1 = buf; | |
4533 size_t len = strlen(os::file_separator()); | |
4534 while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len; | |
4535 jio_snprintf(buf, buflen, "%s+0x%x", p1, offset); | |
4536 } else { | |
4537 jio_snprintf(buf, buflen, PTR_FORMAT, handler); | |
4538 } | |
4539 return buf; | |
4540 } | |
4541 | |
4542 static void print_signal_handler(outputStream* st, int sig, | |
4543 char* buf, size_t buflen) { | |
4544 struct sigaction sa; | |
4545 | |
4546 sigaction(sig, NULL, &sa); | |
4547 | |
4548 // See comment for SIGNIFICANT_SIGNAL_MASK define | |
4549 sa.sa_flags &= SIGNIFICANT_SIGNAL_MASK; | |
4550 | |
4551 st->print("%s: ", os::exception_name(sig, buf, buflen)); | |
4552 | |
4553 address handler = (sa.sa_flags & SA_SIGINFO) | |
4554 ? CAST_FROM_FN_PTR(address, sa.sa_sigaction) | |
4555 : CAST_FROM_FN_PTR(address, sa.sa_handler); | |
4556 | |
4557 if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) { | |
4558 st->print("SIG_DFL"); | |
4559 } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) { | |
4560 st->print("SIG_IGN"); | |
4561 } else { | |
4562 st->print("[%s]", get_signal_handler_name(handler, buf, buflen)); | |
4563 } | |
4564 | |
4565 st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask); | |
4566 | |
4567 address rh = VMError::get_resetted_sighandler(sig); | |
4568 // May be, handler was resetted by VMError? | |
4569 if(rh != NULL) { | |
4570 handler = rh; | |
4571 sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK; | |
4572 } | |
4573 | |
4574 st->print(", sa_flags=" PTR32_FORMAT, sa.sa_flags); | |
4575 | |
4576 // Check: is it our handler? | |
4577 if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) || | |
4578 handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler)) { | |
4579 // It is our signal handler | |
4580 // check for flags, reset system-used one! | |
4581 if((int)sa.sa_flags != os::Linux::get_our_sigflags(sig)) { | |
4582 st->print( | |
4583 ", flags was changed from " PTR32_FORMAT ", consider using jsig library", | |
4584 os::Linux::get_our_sigflags(sig)); | |
4585 } | |
4586 } | |
4587 st->cr(); | |
4588 } | |
4589 | |
4590 | |
4591 #define DO_SIGNAL_CHECK(sig) \ | |
4592 if (!sigismember(&check_signal_done, sig)) \ | |
4593 os::Linux::check_signal_handler(sig) | |
4594 | |
4595 // This method is a periodic task to check for misbehaving JNI applications | |
4596 // under CheckJNI, we can add any periodic checks here | |
4597 | |
4598 void os::run_periodic_checks() { | |
4599 | |
4600 if (check_signals == false) return; | |
4601 | |
4602 // SEGV and BUS if overridden could potentially prevent | |
4603 // generation of hs*.log in the event of a crash, debugging | |
4604 // such a case can be very challenging, so we absolutely | |
4605 // check the following for a good measure: | |
4606 DO_SIGNAL_CHECK(SIGSEGV); | |
4607 DO_SIGNAL_CHECK(SIGILL); | |
4608 DO_SIGNAL_CHECK(SIGFPE); | |
4609 DO_SIGNAL_CHECK(SIGBUS); | |
4610 DO_SIGNAL_CHECK(SIGPIPE); | |
4611 DO_SIGNAL_CHECK(SIGXFSZ); | |
4612 | |
4613 | |
4614 // ReduceSignalUsage allows the user to override these handlers | |
4615 // see comments at the very top and jvm_solaris.h | |
4616 if (!ReduceSignalUsage) { | |
4617 DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL); | |
4618 DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL); | |
4619 DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL); | |
4620 DO_SIGNAL_CHECK(BREAK_SIGNAL); | |
4621 } | |
4622 | |
4623 DO_SIGNAL_CHECK(SR_signum); | |
4624 DO_SIGNAL_CHECK(INTERRUPT_SIGNAL); | |
4625 } | |
4626 | |
4627 typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *); | |
4628 | |
4629 static os_sigaction_t os_sigaction = NULL; | |
4630 | |
4631 void os::Linux::check_signal_handler(int sig) { | |
4632 char buf[O_BUFLEN]; | |
4633 address jvmHandler = NULL; | |
4634 | |
4635 | |
4636 struct sigaction act; | |
4637 if (os_sigaction == NULL) { | |
4638 // only trust the default sigaction, in case it has been interposed | |
4639 os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction"); | |
4640 if (os_sigaction == NULL) return; | |
4641 } | |
4642 | |
4643 os_sigaction(sig, (struct sigaction*)NULL, &act); | |
4644 | |
4645 | |
4646 act.sa_flags &= SIGNIFICANT_SIGNAL_MASK; | |
4647 | |
4648 address thisHandler = (act.sa_flags & SA_SIGINFO) | |
4649 ? CAST_FROM_FN_PTR(address, act.sa_sigaction) | |
4650 : CAST_FROM_FN_PTR(address, act.sa_handler) ; | |
4651 | |
4652 | |
4653 switch(sig) { | |
4654 case SIGSEGV: | |
4655 case SIGBUS: | |
4656 case SIGFPE: | |
4657 case SIGPIPE: | |
4658 case SIGILL: | |
4659 case SIGXFSZ: | |
4660 jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler); | |
4661 break; | |
4662 | |
4663 case SHUTDOWN1_SIGNAL: | |
4664 case SHUTDOWN2_SIGNAL: | |
4665 case SHUTDOWN3_SIGNAL: | |
4666 case BREAK_SIGNAL: | |
4667 jvmHandler = (address)user_handler(); | |
4668 break; | |
4669 | |
4670 case INTERRUPT_SIGNAL: | |
4671 jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL); | |
4672 break; | |
4673 | |
4674 default: | |
4675 if (sig == SR_signum) { | |
4676 jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler); | |
4677 } else { | |
4678 return; | |
4679 } | |
4680 break; | |
4681 } | |
4682 | |
4683 if (thisHandler != jvmHandler) { | |
4684 tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN)); | |
4685 tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN)); | |
4686 tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN)); | |
4687 // No need to check this sig any longer | |
4688 sigaddset(&check_signal_done, sig); | |
4689 } else if(os::Linux::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Linux::get_our_sigflags(sig)) { | |
4690 tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN)); | |
4691 tty->print("expected:" PTR32_FORMAT, os::Linux::get_our_sigflags(sig)); | |
4692 tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags); | |
4693 // No need to check this sig any longer | |
4694 sigaddset(&check_signal_done, sig); | |
4695 } | |
4696 | |
4697 // Dump all the signal | |
4698 if (sigismember(&check_signal_done, sig)) { | |
4699 print_signal_handlers(tty, buf, O_BUFLEN); | |
4700 } | |
4701 } | |
4702 | |
4703 extern void report_error(char* file_name, int line_no, char* title, char* format, ...); | |
4704 | |
4705 extern bool signal_name(int signo, char* buf, size_t len); | |
4706 | |
4707 const char* os::exception_name(int exception_code, char* buf, size_t size) { | |
4708 if (0 < exception_code && exception_code <= SIGRTMAX) { | |
4709 // signal | |
4710 if (!signal_name(exception_code, buf, size)) { | |
4711 jio_snprintf(buf, size, "SIG%d", exception_code); | |
4712 } | |
4713 return buf; | |
4714 } else { | |
4715 return NULL; | |
4716 } | |
4717 } | |
4718 | |
4719 // this is called _before_ the most of global arguments have been parsed | |
4720 void os::init(void) { | |
4721 char dummy; /* used to get a guess on initial stack address */ | |
4722 // first_hrtime = gethrtime(); | |
4723 | |
4724 // With LinuxThreads the JavaMain thread pid (primordial thread) | |
4725 // is different than the pid of the java launcher thread. | |
4726 // So, on Linux, the launcher thread pid is passed to the VM | |
4727 // via the sun.java.launcher.pid property. | |
4728 // Use this property instead of getpid() if it was correctly passed. | |
4729 // See bug 6351349. | |
4730 pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid(); | |
4731 | |
4732 _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid(); | |
4733 | |
4734 clock_tics_per_sec = sysconf(_SC_CLK_TCK); | |
4735 | |
4736 init_random(1234567); | |
4737 | |
4738 ThreadCritical::initialize(); | |
4739 | |
4740 Linux::set_page_size(sysconf(_SC_PAGESIZE)); | |
4741 if (Linux::page_size() == -1) { | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1353
diff
changeset
|
4742 fatal(err_msg("os_linux.cpp: os::init: sysconf failed (%s)", |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1353
diff
changeset
|
4743 strerror(errno))); |
0 | 4744 } |
4745 init_page_sizes((size_t) Linux::page_size()); | |
4746 | |
4747 Linux::initialize_system_info(); | |
4748 | |
4749 // main_thread points to the aboriginal thread | |
4750 Linux::_main_thread = pthread_self(); | |
4751 | |
4752 Linux::clock_init(); | |
4753 initial_time_count = os::elapsed_counter(); | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4754 |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4755 // pthread_condattr initialization for monotonic clock |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4756 int status; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4757 pthread_condattr_t* _condattr = os::Linux::condAttr(); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4758 if ((status = pthread_condattr_init(_condattr)) != 0) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4759 fatal(err_msg("pthread_condattr_init: %s", strerror(status))); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4760 } |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4761 // Only set the clock if CLOCK_MONOTONIC is available |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4762 if (Linux::supports_monotonic_clock()) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4763 if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4764 if (status == EINVAL) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4765 warning("Unable to use monotonic clock with relative timed-waits" \ |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4766 " - changes to the time-of-day clock may have adverse affects"); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4767 } else { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4768 fatal(err_msg("pthread_condattr_setclock: %s", strerror(status))); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4769 } |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4770 } |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4771 } |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4772 // else it defaults to CLOCK_REALTIME |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
4773 |
242 | 4774 pthread_mutex_init(&dl_mutex, NULL); |
10164
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4775 |
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4776 // If the pagesize of the VM is greater than 8K determine the appropriate |
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4777 // number of initial guard pages. The user can change this with the |
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4778 // command line arguments, if needed. |
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4779 if (vm_page_size() > (int)Linux::vm_default_page_size()) { |
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4780 StackYellowPages = 1; |
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4781 StackRedPages = 1; |
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4782 StackShadowPages = round_to((StackShadowPages*Linux::vm_default_page_size()), vm_page_size()) / vm_page_size(); |
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4783 } |
0 | 4784 } |
4785 | |
4786 // To install functions for atexit system call | |
4787 extern "C" { | |
4788 static void perfMemory_exit_helper() { | |
4789 perfMemory_exit(); | |
4790 } | |
4791 } | |
4792 | |
4793 // this is called _after_ the global arguments have been parsed | |
4794 jint os::init_2(void) | |
4795 { | |
4796 Linux::fast_thread_clock_init(); | |
4797 | |
4798 // Allocate a single page and mark it as readable for safepoint polling | |
4799 address polling_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | |
4800 guarantee( polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page" ); | |
4801 | |
4802 os::set_polling_page( polling_page ); | |
4803 | |
4804 #ifndef PRODUCT | |
4805 if(Verbose && PrintMiscellaneous) | |
4806 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); | |
4807 #endif | |
4808 | |
4809 if (!UseMembar) { | |
4810 address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | |
10969
a837fa3d3f86
8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents:
10405
diff
changeset
|
4811 guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page"); |
0 | 4812 os::set_memory_serialize_page( mem_serialize_page ); |
4813 | |
4814 #ifndef PRODUCT | |
4815 if(Verbose && PrintMiscellaneous) | |
4816 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); | |
4817 #endif | |
4818 } | |
4819 | |
4820 // initialize suspend/resume support - must do this before signal_sets_init() | |
4821 if (SR_initialize() != 0) { | |
4822 perror("SR_initialize failed"); | |
4823 return JNI_ERR; | |
4824 } | |
4825 | |
4826 Linux::signal_sets_init(); | |
4827 Linux::install_signal_handlers(); | |
4828 | |
1867
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4829 // Check minimum allowable stack size for thread creation and to initialize |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4830 // the java system classes, including StackOverflowError - depends on page |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4831 // size. Add a page for compiler2 recursion in main thread. |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4832 // Add in 2*BytesPerWord times page size to account for VM stack during |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4833 // class initialization depending on 32 or 64 bit VM. |
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4834 os::Linux::min_stack_allowed = MAX2(os::Linux::min_stack_allowed, |
10164
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4835 (size_t)(StackYellowPages+StackRedPages+StackShadowPages) * Linux::page_size() + |
b4081e9714ec
8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents:
10157
diff
changeset
|
4836 (2*BytesPerWord COMPILER2_PRESENT(+1)) * Linux::vm_default_page_size()); |
1867
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4837 |
0 | 4838 size_t threadStackSizeInBytes = ThreadStackSize * K; |
4839 if (threadStackSizeInBytes != 0 && | |
1867
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4840 threadStackSizeInBytes < os::Linux::min_stack_allowed) { |
0 | 4841 tty->print_cr("\nThe stack size specified is too small, " |
4842 "Specify at least %dk", | |
1867
b6aedd1acdc0
6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents:
1865
diff
changeset
|
4843 os::Linux::min_stack_allowed/ K); |
0 | 4844 return JNI_ERR; |
4845 } | |
4846 | |
4847 // Make the stack size a multiple of the page size so that | |
4848 // the yellow/red zones can be guarded. | |
4849 JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, | |
4850 vm_page_size())); | |
4851 | |
4852 Linux::capture_initial_stack(JavaThread::stack_size_at_create()); | |
4853 | |
4854 Linux::libpthread_init(); | |
4855 if (PrintMiscellaneous && (Verbose || WizardMode)) { | |
4856 tty->print_cr("[HotSpot is running with %s, %s(%s)]\n", | |
4857 Linux::glibc_version(), Linux::libpthread_version(), | |
4858 Linux::is_floating_stack() ? "floating stack" : "fixed stack"); | |
4859 } | |
4860 | |
141 | 4861 if (UseNUMA) { |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4862 if (!Linux::libnuma_init()) { |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4863 UseNUMA = false; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4864 } else { |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4865 if ((Linux::numa_max_node() < 1)) { |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4866 // There's only one node(they start from 0), disable NUMA. |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4867 UseNUMA = false; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4868 } |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4869 } |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
4870 // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way |
3292
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4871 // we can make the adaptive lgrp chunk resizing work. If the user specified |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
4872 // both UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn and |
3292
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4873 // disable adaptive resizing. |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
4874 if (UseNUMA && UseLargePages && !can_commit_large_page_memory()) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
4875 if (FLAG_IS_DEFAULT(UseNUMA)) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
4876 UseNUMA = false; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
4877 } else { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
4878 if (FLAG_IS_DEFAULT(UseLargePages) && |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
4879 FLAG_IS_DEFAULT(UseSHM) && |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
4880 FLAG_IS_DEFAULT(UseHugeTLBFS)) { |
3292
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4881 UseLargePages = false; |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4882 } else { |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
4883 warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing"); |
3292
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4884 UseAdaptiveSizePolicy = false; |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4885 UseAdaptiveNUMAChunkSizing = false; |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4886 } |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4887 } |
c303b3532d4a
7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents:
3290
diff
changeset
|
4888 } |
462
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4889 if (!UseNUMA && ForceNUMA) { |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4890 UseNUMA = true; |
85f1b9537f70
6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents:
356
diff
changeset
|
4891 } |
141 | 4892 } |
4893 | |
0 | 4894 if (MaxFDLimit) { |
4895 // set the number of file descriptors to max. print out error | |
4896 // if getrlimit/setrlimit fails but continue regardless. | |
4897 struct rlimit nbr_files; | |
4898 int status = getrlimit(RLIMIT_NOFILE, &nbr_files); | |
4899 if (status != 0) { | |
4900 if (PrintMiscellaneous && (Verbose || WizardMode)) | |
4901 perror("os::init_2 getrlimit failed"); | |
4902 } else { | |
4903 nbr_files.rlim_cur = nbr_files.rlim_max; | |
4904 status = setrlimit(RLIMIT_NOFILE, &nbr_files); | |
4905 if (status != 0) { | |
4906 if (PrintMiscellaneous && (Verbose || WizardMode)) | |
4907 perror("os::init_2 setrlimit failed"); | |
4908 } | |
4909 } | |
4910 } | |
4911 | |
4912 // Initialize lock used to serialize thread creation (see os::create_thread) | |
4913 Linux::set_createThread_lock(new Mutex(Mutex::leaf, "createThread_lock", false)); | |
4914 | |
4915 // at-exit methods are called in the reverse order of their registration. | |
4916 // atexit functions are called on return from main or as a result of a | |
4917 // call to exit(3C). There can be only 32 of these functions registered | |
4918 // and atexit() does not set errno. | |
4919 | |
4920 if (PerfAllowAtExitRegistration) { | |
4921 // only register atexit functions if PerfAllowAtExitRegistration is set. | |
4922 // atexit functions can be delayed until process exit time, which | |
4923 // can be problematic for embedded VM situations. Embedded VMs should | |
4924 // call DestroyJavaVM() to assure that VM resources are released. | |
4925 | |
4926 // note: perfMemory_exit_helper atexit function may be removed in | |
4927 // the future if the appropriate cleanup code can be added to the | |
4928 // VM_Exit VMOperation's doit method. | |
4929 if (atexit(perfMemory_exit_helper) != 0) { | |
4930 warning("os::init2 atexit(perfMemory_exit_helper) failed"); | |
4931 } | |
4932 } | |
4933 | |
4934 // initialize thread priority policy | |
4935 prio_init(); | |
4936 | |
4937 return JNI_OK; | |
4938 } | |
4939 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4940 // this is called at the end of vm_initialization |
3802
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4941 void os::init_3(void) |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4942 { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4943 #ifdef JAVASE_EMBEDDED |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4944 // Start the MemNotifyThread |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4945 if (LowMemoryProtection) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4946 MemNotifyThread::start(); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4947 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4948 return; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4949 #endif |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
4950 } |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
4951 |
0 | 4952 // Mark the polling page as unreadable |
4953 void os::make_polling_page_unreadable(void) { | |
4954 if( !guard_memory((char*)_polling_page, Linux::page_size()) ) | |
4955 fatal("Could not disable polling page"); | |
4956 }; | |
4957 | |
4958 // Mark the polling page as readable | |
4959 void os::make_polling_page_readable(void) { | |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
4960 if( !linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) { |
0 | 4961 fatal("Could not enable polling page"); |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
235
diff
changeset
|
4962 } |
0 | 4963 }; |
4964 | |
4965 int os::active_processor_count() { | |
4966 // Linux doesn't yet have a (official) notion of processor sets, | |
4967 // so just return the number of online processors. | |
4968 int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN); | |
4969 assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check"); | |
4970 return online_cpus; | |
4971 } | |
4972 | |
4006 | 4973 void os::set_native_thread_name(const char *name) { |
4974 // Not yet implemented. | |
4975 return; | |
4976 } | |
4977 | |
0 | 4978 bool os::distribute_processes(uint length, uint* distribution) { |
4979 // Not yet implemented. | |
4980 return false; | |
4981 } | |
4982 | |
4983 bool os::bind_to_processor(uint processor_id) { | |
4984 // Not yet implemented. | |
4985 return false; | |
4986 } | |
4987 | |
4988 /// | |
4989 | |
10405 | 4990 void os::SuspendedThreadTask::internal_do_task() { |
4991 if (do_suspend(_thread->osthread())) { | |
4992 SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext()); | |
4993 do_task(context); | |
4994 do_resume(_thread->osthread()); | |
4995 } | |
4996 } | |
4997 | |
4998 class PcFetcher : public os::SuspendedThreadTask { | |
4999 public: | |
5000 PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {} | |
5001 ExtendedPC result(); | |
5002 protected: | |
5003 void do_task(const os::SuspendedThreadTaskContext& context); | |
5004 private: | |
5005 ExtendedPC _epc; | |
5006 }; | |
5007 | |
5008 ExtendedPC PcFetcher::result() { | |
5009 guarantee(is_done(), "task is not done yet."); | |
5010 return _epc; | |
5011 } | |
5012 | |
5013 void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) { | |
5014 Thread* thread = context.thread(); | |
5015 OSThread* osthread = thread->osthread(); | |
5016 if (osthread->ucontext() != NULL) { | |
5017 _epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext()); | |
5018 } else { | |
5019 // NULL context is unexpected, double-check this is the VMThread | |
5020 guarantee(thread->is_VM_thread(), "can only be called for VMThread"); | |
5021 } | |
5022 } | |
5023 | |
0 | 5024 // Suspends the target using the signal mechanism and then grabs the PC before |
5025 // resuming the target. Used by the flat-profiler only | |
5026 ExtendedPC os::get_thread_pc(Thread* thread) { | |
5027 // Make sure that it is called by the watcher for the VMThread | |
5028 assert(Thread::current()->is_Watcher_thread(), "Must be watcher"); | |
5029 assert(thread->is_VM_thread(), "Can only be called for VMThread"); | |
5030 | |
10405 | 5031 PcFetcher fetcher(thread); |
5032 fetcher.run(); | |
5033 return fetcher.result(); | |
0 | 5034 } |
5035 | |
5036 int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime) | |
5037 { | |
5038 if (is_NPTL()) { | |
5039 return pthread_cond_timedwait(_cond, _mutex, _abstime); | |
5040 } else { | |
5041 // 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control | |
5042 // word back to default 64bit precision if condvar is signaled. Java | |
5043 // wants 53bit precision. Save and restore current value. | |
5044 int fpu = get_fpu_control_word(); | |
5045 int status = pthread_cond_timedwait(_cond, _mutex, _abstime); | |
5046 set_fpu_control_word(fpu); | |
5047 return status; | |
5048 } | |
5049 } | |
5050 | |
5051 //////////////////////////////////////////////////////////////////////////////// | |
5052 // debug support | |
5053 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5054 bool os::find(address addr, outputStream* st) { |
0 | 5055 Dl_info dlinfo; |
5056 memset(&dlinfo, 0, sizeof(dlinfo)); | |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
5057 if (dladdr(addr, &dlinfo) != 0) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5058 st->print(PTR_FORMAT ": ", addr); |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
5059 if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5060 st->print("%s+%#x", dlinfo.dli_sname, |
0 | 5061 addr - (intptr_t)dlinfo.dli_saddr); |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
5062 } else if (dlinfo.dli_fbase != NULL) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5063 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase); |
0 | 5064 } else { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5065 st->print("<absolute address>"); |
0 | 5066 } |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
5067 if (dlinfo.dli_fname != NULL) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5068 st->print(" in %s", dlinfo.dli_fname); |
0 | 5069 } |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
5070 if (dlinfo.dli_fbase != NULL) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5071 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); |
0 | 5072 } |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5073 st->cr(); |
0 | 5074 |
5075 if (Verbose) { | |
5076 // decode some bytes around the PC | |
9060
cc32ccaaf47f
8003310: Enable -Wunused-function when compiling with gcc
mikael
parents:
9059
diff
changeset
|
5077 address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size()); |
cc32ccaaf47f
8003310: Enable -Wunused-function when compiling with gcc
mikael
parents:
9059
diff
changeset
|
5078 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size()); |
0 | 5079 address lowest = (address) dlinfo.dli_sname; |
5080 if (!lowest) lowest = (address) dlinfo.dli_fbase; | |
5081 if (begin < lowest) begin = lowest; | |
5082 Dl_info dlinfo2; | |
11092
59b052799158
8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents:
10986
diff
changeset
|
5083 if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr |
0 | 5084 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) |
5085 end = (address) dlinfo2.dli_saddr; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5086 Disassembler::decode(begin, end, st); |
0 | 5087 } |
5088 return true; | |
5089 } | |
5090 return false; | |
5091 } | |
5092 | |
5093 //////////////////////////////////////////////////////////////////////////////// | |
5094 // misc | |
5095 | |
5096 // This does not do anything on Linux. This is basically a hook for being | |
5097 // able to use structured exception handling (thread-local exception filters) | |
5098 // on, e.g., Win32. | |
5099 void | |
5100 os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, | |
5101 JavaCallArguments* args, Thread* thread) { | |
5102 f(value, method, args, thread); | |
5103 } | |
5104 | |
5105 void os::print_statistics() { | |
5106 } | |
5107 | |
5108 int os::message_box(const char* title, const char* message) { | |
5109 int i; | |
5110 fdStream err(defaultStream::error_fd()); | |
5111 for (i = 0; i < 78; i++) err.print_raw("="); | |
5112 err.cr(); | |
5113 err.print_raw_cr(title); | |
5114 for (i = 0; i < 78; i++) err.print_raw("-"); | |
5115 err.cr(); | |
5116 err.print_raw_cr(message); | |
5117 for (i = 0; i < 78; i++) err.print_raw("="); | |
5118 err.cr(); | |
5119 | |
5120 char buf[16]; | |
5121 // Prevent process from exiting upon "read error" without consuming all CPU | |
5122 while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); } | |
5123 | |
5124 return buf[0] == 'y' || buf[0] == 'Y'; | |
5125 } | |
5126 | |
5127 int os::stat(const char *path, struct stat *sbuf) { | |
5128 char pathbuf[MAX_PATH]; | |
5129 if (strlen(path) > MAX_PATH - 1) { | |
5130 errno = ENAMETOOLONG; | |
5131 return -1; | |
5132 } | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5133 os::native_path(strcpy(pathbuf, path)); |
0 | 5134 return ::stat(pathbuf, sbuf); |
5135 } | |
5136 | |
5137 bool os::check_heap(bool force) { | |
5138 return true; | |
5139 } | |
5140 | |
5141 int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) { | |
5142 return ::vsnprintf(buf, count, format, args); | |
5143 } | |
5144 | |
5145 // Is a (classpath) directory empty? | |
5146 bool os::dir_is_empty(const char* path) { | |
5147 DIR *dir = NULL; | |
5148 struct dirent *ptr; | |
5149 | |
5150 dir = opendir(path); | |
5151 if (dir == NULL) return true; | |
5152 | |
5153 /* Scan the directory */ | |
5154 bool result = true; | |
5155 char buf[sizeof(struct dirent) + MAX_PATH]; | |
5156 while (result && (ptr = ::readdir(dir)) != NULL) { | |
5157 if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) { | |
5158 result = false; | |
5159 } | |
5160 } | |
5161 closedir(dir); | |
5162 return result; | |
5163 } | |
5164 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5165 // This code originates from JDK's sysOpen and open64_w |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5166 // from src/solaris/hpi/src/system_md.c |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5167 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5168 #ifndef O_DELETE |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5169 #define O_DELETE 0x10000 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5170 #endif |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5171 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5172 // Open a file. Unlink the file immediately after open returns |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5173 // if the specified oflag has the O_DELETE flag set. |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5174 // O_DELETE is used only in j2se/src/share/native/java/util/zip/ZipFile.c |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5175 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5176 int os::open(const char *path, int oflag, int mode) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5177 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5178 if (strlen(path) > MAX_PATH - 1) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5179 errno = ENAMETOOLONG; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5180 return -1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5181 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5182 int fd; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5183 int o_delete = (oflag & O_DELETE); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5184 oflag = oflag & ~O_DELETE; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5185 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5186 fd = ::open64(path, oflag, mode); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5187 if (fd == -1) return -1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5188 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5189 //If the open succeeded, the file might still be a directory |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5190 { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5191 struct stat64 buf64; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5192 int ret = ::fstat64(fd, &buf64); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5193 int st_mode = buf64.st_mode; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5194 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5195 if (ret != -1) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5196 if ((st_mode & S_IFMT) == S_IFDIR) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5197 errno = EISDIR; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5198 ::close(fd); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5199 return -1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5200 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5201 } else { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5202 ::close(fd); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5203 return -1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5204 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5205 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5206 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5207 /* |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5208 * All file descriptors that are opened in the JVM and not |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5209 * specifically destined for a subprocess should have the |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5210 * close-on-exec flag set. If we don't set it, then careless 3rd |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5211 * party native code might fork and exec without closing all |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5212 * appropriate file descriptors (e.g. as we do in closeDescriptors in |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5213 * UNIXProcess.c), and this in turn might: |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5214 * |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5215 * - cause end-of-file to fail to be detected on some file |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5216 * descriptors, resulting in mysterious hangs, or |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5217 * |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5218 * - might cause an fopen in the subprocess to fail on a system |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5219 * suffering from bug 1085341. |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5220 * |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5221 * (Yes, the default setting of the close-on-exec flag is a Unix |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5222 * design flaw) |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5223 * |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5224 * See: |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5225 * 1085341: 32-bit stdio routines should support file descriptors >255 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5226 * 4843136: (process) pipe file descriptor from Runtime.exec not being closed |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5227 * 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5228 */ |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5229 #ifdef FD_CLOEXEC |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5230 { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5231 int flags = ::fcntl(fd, F_GETFD); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5232 if (flags != -1) |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5233 ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5234 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5235 #endif |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5236 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5237 if (o_delete != 0) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5238 ::unlink(path); |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5239 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5240 return fd; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5241 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5242 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5243 |
0 | 5244 // create binary file, rewriting existing file if required |
5245 int os::create_binary_file(const char* path, bool rewrite_existing) { | |
5246 int oflags = O_WRONLY | O_CREAT; | |
5247 if (!rewrite_existing) { | |
5248 oflags |= O_EXCL; | |
5249 } | |
5250 return ::open64(path, oflags, S_IREAD | S_IWRITE); | |
5251 } | |
5252 | |
5253 // return current position of file pointer | |
5254 jlong os::current_file_offset(int fd) { | |
5255 return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR); | |
5256 } | |
5257 | |
5258 // move file pointer to the specified offset | |
5259 jlong os::seek_to_file_offset(int fd, jlong offset) { | |
5260 return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET); | |
5261 } | |
5262 | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5263 // This code originates from JDK's sysAvailable |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5264 // from src/solaris/hpi/src/native_threads/src/sys_api_td.c |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5265 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5266 int os::available(int fd, jlong *bytes) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5267 jlong cur, end; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5268 int mode; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5269 struct stat64 buf64; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5270 |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5271 if (::fstat64(fd, &buf64) >= 0) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5272 mode = buf64.st_mode; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5273 if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5274 /* |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5275 * XXX: is the following call interruptible? If so, this might |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5276 * need to go through the INTERRUPT_IO() wrapper as for other |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5277 * blocking, interruptible calls in this file. |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5278 */ |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5279 int n; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5280 if (::ioctl(fd, FIONREAD, &n) >= 0) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5281 *bytes = n; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5282 return 1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5283 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5284 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5285 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5286 if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5287 return 0; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5288 } else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5289 return 0; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5290 } else if (::lseek64(fd, cur, SEEK_SET) == -1) { |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5291 return 0; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5292 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5293 *bytes = end - cur; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5294 return 1; |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5295 } |
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5296 |
2033
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
5297 int os::socket_available(int fd, jint *pbytes) { |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
5298 // Linux doc says EINTR not returned, unlike Solaris |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
5299 int ret = ::ioctl(fd, FIONREAD, pbytes); |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
5300 |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
5301 //%% note ioctl can return 0 when successful, JVM_SocketAvailable |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
5302 // is expected to return 0 on failure and 1 on success to the jdk. |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
5303 return (ret < 0) ? 0 : 1; |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
5304 } |
03e1b9fce89d
7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents:
2023
diff
changeset
|
5305 |
0 | 5306 // Map a block of memory. |
6197 | 5307 char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, |
0 | 5308 char *addr, size_t bytes, bool read_only, |
5309 bool allow_exec) { | |
5310 int prot; | |
5909 | 5311 int flags = MAP_PRIVATE; |
0 | 5312 |
5313 if (read_only) { | |
5314 prot = PROT_READ; | |
5315 } else { | |
5316 prot = PROT_READ | PROT_WRITE; | |
5317 } | |
5318 | |
5319 if (allow_exec) { | |
5320 prot |= PROT_EXEC; | |
5321 } | |
5322 | |
5323 if (addr != NULL) { | |
5324 flags |= MAP_FIXED; | |
5325 } | |
5326 | |
5327 char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags, | |
5328 fd, file_offset); | |
5329 if (mapped_address == MAP_FAILED) { | |
5330 return NULL; | |
5331 } | |
5332 return mapped_address; | |
5333 } | |
5334 | |
5335 | |
5336 // Remap a block of memory. | |
6197 | 5337 char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, |
0 | 5338 char *addr, size_t bytes, bool read_only, |
5339 bool allow_exec) { | |
5340 // same as map_memory() on this OS | |
5341 return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only, | |
5342 allow_exec); | |
5343 } | |
5344 | |
5345 | |
5346 // Unmap a block of memory. | |
6197 | 5347 bool os::pd_unmap_memory(char* addr, size_t bytes) { |
0 | 5348 return munmap(addr, bytes) == 0; |
5349 } | |
5350 | |
5351 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time); | |
5352 | |
5353 static clockid_t thread_cpu_clockid(Thread* thread) { | |
5354 pthread_t tid = thread->osthread()->pthread_id(); | |
5355 clockid_t clockid; | |
5356 | |
5357 // Get thread clockid | |
5358 int rc = os::Linux::pthread_getcpuclockid(tid, &clockid); | |
5359 assert(rc == 0, "pthread_getcpuclockid is expected to return 0 code"); | |
5360 return clockid; | |
5361 } | |
5362 | |
5363 // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool) | |
5364 // are used by JVM M&M and JVMTI to get user+sys or user CPU time | |
5365 // of a thread. | |
5366 // | |
5367 // current_thread_cpu_time() and thread_cpu_time(Thread*) returns | |
5368 // the fast estimate available on the platform. | |
5369 | |
5370 jlong os::current_thread_cpu_time() { | |
5371 if (os::Linux::supports_fast_thread_cpu_time()) { | |
5372 return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID); | |
5373 } else { | |
5374 // return user + sys since the cost is the same | |
5375 return slow_thread_cpu_time(Thread::current(), true /* user + sys */); | |
5376 } | |
5377 } | |
5378 | |
5379 jlong os::thread_cpu_time(Thread* thread) { | |
5380 // consistent with what current_thread_cpu_time() returns | |
5381 if (os::Linux::supports_fast_thread_cpu_time()) { | |
5382 return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread)); | |
5383 } else { | |
5384 return slow_thread_cpu_time(thread, true /* user + sys */); | |
5385 } | |
5386 } | |
5387 | |
5388 jlong os::current_thread_cpu_time(bool user_sys_cpu_time) { | |
5389 if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) { | |
5390 return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID); | |
5391 } else { | |
5392 return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time); | |
5393 } | |
5394 } | |
5395 | |
5396 jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) { | |
5397 if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) { | |
5398 return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread)); | |
5399 } else { | |
5400 return slow_thread_cpu_time(thread, user_sys_cpu_time); | |
5401 } | |
5402 } | |
5403 | |
5404 // | |
5405 // -1 on error. | |
5406 // | |
5407 | |
5408 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) { | |
5409 static bool proc_task_unchecked = true; | |
5410 static const char *proc_stat_path = "/proc/%d/stat"; | |
5411 pid_t tid = thread->osthread()->thread_id(); | |
5412 char *s; | |
5413 char stat[2048]; | |
5414 int statlen; | |
5415 char proc_name[64]; | |
5416 int count; | |
5417 long sys_time, user_time; | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5418 char cdummy; |
0 | 5419 int idummy; |
5420 long ldummy; | |
5421 FILE *fp; | |
5422 | |
5423 // The /proc/<tid>/stat aggregates per-process usage on | |
5424 // new Linux kernels 2.6+ where NPTL is supported. | |
5425 // The /proc/self/task/<tid>/stat still has the per-thread usage. | |
5426 // See bug 6328462. | |
8099
4c1d8002ffb1
8004495: [parfait] False positive Buffer overflow in hotspot/src/os/linux/vm/os_linux.cpp
hseigel
parents:
8067
diff
changeset
|
5427 // There possibly can be cases where there is no directory |
4c1d8002ffb1
8004495: [parfait] False positive Buffer overflow in hotspot/src/os/linux/vm/os_linux.cpp
hseigel
parents:
8067
diff
changeset
|
5428 // /proc/self/task, so we check its availability. |
0 | 5429 if (proc_task_unchecked && os::Linux::is_NPTL()) { |
5430 // This is executed only once | |
5431 proc_task_unchecked = false; | |
5432 fp = fopen("/proc/self/task", "r"); | |
5433 if (fp != NULL) { | |
5434 proc_stat_path = "/proc/self/task/%d/stat"; | |
5435 fclose(fp); | |
5436 } | |
5437 } | |
5438 | |
5439 sprintf(proc_name, proc_stat_path, tid); | |
5440 fp = fopen(proc_name, "r"); | |
5441 if ( fp == NULL ) return -1; | |
5442 statlen = fread(stat, 1, 2047, fp); | |
5443 stat[statlen] = '\0'; | |
5444 fclose(fp); | |
5445 | |
5446 // Skip pid and the command string. Note that we could be dealing with | |
5447 // weird command names, e.g. user could decide to rename java launcher | |
5448 // to "java 1.4.2 :)", then the stat file would look like | |
5449 // 1234 (java 1.4.2 :)) R ... ... | |
5450 // We don't really need to know the command string, just find the last | |
5451 // occurrence of ")" and then start parsing from there. See bug 4726580. | |
5452 s = strrchr(stat, ')'); | |
5453 if (s == NULL ) return -1; | |
5454 | |
5455 // Skip blank chars | |
5456 do s++; while (isspace(*s)); | |
5457 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5458 count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu", |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5459 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy, |
0 | 5460 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy, |
5461 &user_time, &sys_time); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
5462 if ( count != 13 ) return -1; |
0 | 5463 if (user_sys_cpu_time) { |
5464 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec); | |
5465 } else { | |
5466 return (jlong)user_time * (1000000000 / clock_tics_per_sec); | |
5467 } | |
5468 } | |
5469 | |
5470 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { | |
5471 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits | |
5472 info_ptr->may_skip_backward = false; // elapsed time not wall time | |
5473 info_ptr->may_skip_forward = false; // elapsed time not wall time | |
5474 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned | |
5475 } | |
5476 | |
5477 void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { | |
5478 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits | |
5479 info_ptr->may_skip_backward = false; // elapsed time not wall time | |
5480 info_ptr->may_skip_forward = false; // elapsed time not wall time | |
5481 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned | |
5482 } | |
5483 | |
5484 bool os::is_thread_cpu_time_supported() { | |
5485 return true; | |
5486 } | |
5487 | |
5488 // System loadavg support. Returns -1 if load average cannot be obtained. | |
5489 // Linux doesn't yet have a (official) notion of processor sets, | |
5490 // so just return the system wide load average. | |
5491 int os::loadavg(double loadavg[], int nelem) { | |
5492 return ::getloadavg(loadavg, nelem); | |
5493 } | |
5494 | |
5495 void os::pause() { | |
5496 char filename[MAX_PATH]; | |
5497 if (PauseAtStartupFile && PauseAtStartupFile[0]) { | |
5498 jio_snprintf(filename, MAX_PATH, PauseAtStartupFile); | |
5499 } else { | |
5500 jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id()); | |
5501 } | |
5502 | |
5503 int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); | |
5504 if (fd != -1) { | |
5505 struct stat buf; | |
1980
828eafbd85cc
6348631: remove the use of the HPI library from Hotspot
ikrylov
parents:
1972
diff
changeset
|
5506 ::close(fd); |
0 | 5507 while (::stat(filename, &buf) == 0) { |
5508 (void)::poll(NULL, 0, 100); | |
5509 } | |
5510 } else { | |
5511 jio_fprintf(stderr, | |
5512 "Could not open pause file '%s', continuing immediately.\n", filename); | |
5513 } | |
5514 } | |
5515 | |
5516 | |
5517 // Refer to the comments in os_solaris.cpp park-unpark. | |
5518 // | |
5519 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can | |
5520 // hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable. | |
5521 // For specifics regarding the bug see GLIBC BUGID 261237 : | |
5522 // http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html. | |
5523 // Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future | |
5524 // will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar | |
5525 // is used. (The simple C test-case provided in the GLIBC bug report manifests the | |
5526 // hang). The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos() | |
5527 // and monitorenter when we're using 1-0 locking. All those operations may result in | |
5528 // calls to pthread_cond_timedwait(). Using LD_ASSUME_KERNEL to use an older version | |
5529 // of libpthread avoids the problem, but isn't practical. | |
5530 // | |
5531 // Possible remedies: | |
5532 // | |
5533 // 1. Establish a minimum relative wait time. 50 to 100 msecs seems to work. | |
5534 // This is palliative and probabilistic, however. If the thread is preempted | |
5535 // between the call to compute_abstime() and pthread_cond_timedwait(), more | |
5536 // than the minimum period may have passed, and the abstime may be stale (in the | |
5537 // past) resultin in a hang. Using this technique reduces the odds of a hang | |
5538 // but the JVM is still vulnerable, particularly on heavily loaded systems. | |
5539 // | |
5540 // 2. Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead | |
5541 // of the usual flag-condvar-mutex idiom. The write side of the pipe is set | |
5542 // NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo) | |
5543 // reduces to poll()+read(). This works well, but consumes 2 FDs per extant | |
5544 // thread. | |
5545 // | |
5546 // 3. Embargo pthread_cond_timedwait() and implement a native "chron" thread | |
5547 // that manages timeouts. We'd emulate pthread_cond_timedwait() by enqueuing | |
5548 // a timeout request to the chron thread and then blocking via pthread_cond_wait(). | |
5549 // This also works well. In fact it avoids kernel-level scalability impediments | |
5550 // on certain platforms that don't handle lots of active pthread_cond_timedwait() | |
5551 // timers in a graceful fashion. | |
5552 // | |
5553 // 4. When the abstime value is in the past it appears that control returns | |
5554 // correctly from pthread_cond_timedwait(), but the condvar is left corrupt. | |
5555 // Subsequent timedwait/wait calls may hang indefinitely. Given that, we | |
5556 // can avoid the problem by reinitializing the condvar -- by cond_destroy() | |
5557 // followed by cond_init() -- after all calls to pthread_cond_timedwait(). | |
5558 // It may be possible to avoid reinitialization by checking the return | |
5559 // value from pthread_cond_timedwait(). In addition to reinitializing the | |
5560 // condvar we must establish the invariant that cond_signal() is only called | |
5561 // within critical sections protected by the adjunct mutex. This prevents | |
5562 // cond_signal() from "seeing" a condvar that's in the midst of being | |
5563 // reinitialized or that is corrupt. Sadly, this invariant obviates the | |
5564 // desirable signal-after-unlock optimization that avoids futile context switching. | |
5565 // | |
5566 // I'm also concerned that some versions of NTPL might allocate an auxilliary | |
5567 // structure when a condvar is used or initialized. cond_destroy() would | |
5568 // release the helper structure. Our reinitialize-after-timedwait fix | |
5569 // put excessive stress on malloc/free and locks protecting the c-heap. | |
5570 // | |
5571 // We currently use (4). See the WorkAroundNTPLTimedWaitHang flag. | |
5572 // It may be possible to refine (4) by checking the kernel and NTPL verisons | |
5573 // and only enabling the work-around for vulnerable environments. | |
5574 | |
5575 // utility to compute the abstime argument to timedwait: | |
5576 // millis is the relative timeout time | |
5577 // abstime will be the absolute timeout time | |
5578 // TODO: replace compute_abstime() with unpackTime() | |
5579 | |
5580 static struct timespec* compute_abstime(timespec* abstime, jlong millis) { | |
5581 if (millis < 0) millis = 0; | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5582 |
0 | 5583 jlong seconds = millis / 1000; |
5584 millis %= 1000; | |
5585 if (seconds > 50000000) { // see man cond_timedwait(3T) | |
5586 seconds = 50000000; | |
5587 } | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5588 |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5589 if (os::Linux::supports_monotonic_clock()) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5590 struct timespec now; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5591 int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5592 assert_status(status == 0, status, "clock_gettime"); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5593 abstime->tv_sec = now.tv_sec + seconds; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5594 long nanos = now.tv_nsec + millis * NANOSECS_PER_MILLISEC; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5595 if (nanos >= NANOSECS_PER_SEC) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5596 abstime->tv_sec += 1; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5597 nanos -= NANOSECS_PER_SEC; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5598 } |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5599 abstime->tv_nsec = nanos; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5600 } else { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5601 struct timeval now; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5602 int status = gettimeofday(&now, NULL); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5603 assert(status == 0, "gettimeofday"); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5604 abstime->tv_sec = now.tv_sec + seconds; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5605 long usec = now.tv_usec + millis * 1000; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5606 if (usec >= 1000000) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5607 abstime->tv_sec += 1; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5608 usec -= 1000000; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5609 } |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5610 abstime->tv_nsec = usec * 1000; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5611 } |
0 | 5612 return abstime; |
5613 } | |
5614 | |
5615 | |
5616 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately. | |
5617 // Conceptually TryPark() should be equivalent to park(0). | |
5618 | |
5619 int os::PlatformEvent::TryPark() { | |
5620 for (;;) { | |
5621 const int v = _Event ; | |
5622 guarantee ((v == 0) || (v == 1), "invariant") ; | |
5623 if (Atomic::cmpxchg (0, &_Event, v) == v) return v ; | |
5624 } | |
5625 } | |
5626 | |
5627 void os::PlatformEvent::park() { // AKA "down()" | |
5628 // Invariant: Only the thread associated with the Event/PlatformEvent | |
5629 // may call park(). | |
5630 // TODO: assert that _Assoc != NULL or _Assoc == Self | |
5631 int v ; | |
5632 for (;;) { | |
5633 v = _Event ; | |
5634 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ; | |
5635 } | |
5636 guarantee (v >= 0, "invariant") ; | |
5637 if (v == 0) { | |
5638 // Do this the hard way by blocking ... | |
5639 int status = pthread_mutex_lock(_mutex); | |
5640 assert_status(status == 0, status, "mutex_lock"); | |
5641 guarantee (_nParked == 0, "invariant") ; | |
5642 ++ _nParked ; | |
5643 while (_Event < 0) { | |
5644 status = pthread_cond_wait(_cond, _mutex); | |
5645 // for some reason, under 2.7 lwp_cond_wait() may return ETIME ... | |
5646 // Treat this the same as if the wait was interrupted | |
5647 if (status == ETIME) { status = EINTR; } | |
5648 assert_status(status == 0 || status == EINTR, status, "cond_wait"); | |
5649 } | |
5650 -- _nParked ; | |
5651 | |
5652 _Event = 0 ; | |
5653 status = pthread_mutex_unlock(_mutex); | |
5654 assert_status(status == 0, status, "mutex_unlock"); | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5655 // Paranoia to ensure our locked and lock-free paths interact |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5656 // correctly with each other. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5657 OrderAccess::fence(); |
0 | 5658 } |
5659 guarantee (_Event >= 0, "invariant") ; | |
5660 } | |
5661 | |
5662 int os::PlatformEvent::park(jlong millis) { | |
5663 guarantee (_nParked == 0, "invariant") ; | |
5664 | |
5665 int v ; | |
5666 for (;;) { | |
5667 v = _Event ; | |
5668 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ; | |
5669 } | |
5670 guarantee (v >= 0, "invariant") ; | |
5671 if (v != 0) return OS_OK ; | |
5672 | |
5673 // We do this the hard way, by blocking the thread. | |
5674 // Consider enforcing a minimum timeout value. | |
5675 struct timespec abst; | |
5676 compute_abstime(&abst, millis); | |
5677 | |
5678 int ret = OS_TIMEOUT; | |
5679 int status = pthread_mutex_lock(_mutex); | |
5680 assert_status(status == 0, status, "mutex_lock"); | |
5681 guarantee (_nParked == 0, "invariant") ; | |
5682 ++_nParked ; | |
5683 | |
5684 // Object.wait(timo) will return because of | |
5685 // (a) notification | |
5686 // (b) timeout | |
5687 // (c) thread.interrupt | |
5688 // | |
5689 // Thread.interrupt and object.notify{All} both call Event::set. | |
5690 // That is, we treat thread.interrupt as a special case of notification. | |
5691 // The underlying Solaris implementation, cond_timedwait, admits | |
5692 // spurious/premature wakeups, but the JLS/JVM spec prevents the | |
5693 // JVM from making those visible to Java code. As such, we must | |
5694 // filter out spurious wakeups. We assume all ETIME returns are valid. | |
5695 // | |
5696 // TODO: properly differentiate simultaneous notify+interrupt. | |
5697 // In that case, we should propagate the notify to another waiter. | |
5698 | |
5699 while (_Event < 0) { | |
5700 status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst); | |
5701 if (status != 0 && WorkAroundNPTLTimedWaitHang) { | |
5702 pthread_cond_destroy (_cond); | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5703 pthread_cond_init (_cond, os::Linux::condAttr()) ; |
0 | 5704 } |
5705 assert_status(status == 0 || status == EINTR || | |
5706 status == ETIME || status == ETIMEDOUT, | |
5707 status, "cond_timedwait"); | |
5708 if (!FilterSpuriousWakeups) break ; // previous semantics | |
5709 if (status == ETIME || status == ETIMEDOUT) break ; | |
5710 // We consume and ignore EINTR and spurious wakeups. | |
5711 } | |
5712 --_nParked ; | |
5713 if (_Event >= 0) { | |
5714 ret = OS_OK; | |
5715 } | |
5716 _Event = 0 ; | |
5717 status = pthread_mutex_unlock(_mutex); | |
5718 assert_status(status == 0, status, "mutex_unlock"); | |
5719 assert (_nParked == 0, "invariant") ; | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5720 // Paranoia to ensure our locked and lock-free paths interact |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5721 // correctly with each other. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5722 OrderAccess::fence(); |
0 | 5723 return ret; |
5724 } | |
5725 | |
5726 void os::PlatformEvent::unpark() { | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5727 // Transitions for _Event: |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5728 // 0 :=> 1 |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5729 // 1 :=> 1 |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5730 // -1 :=> either 0 or 1; must signal target thread |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5731 // That is, we can safely transition _Event from -1 to either |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5732 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5733 // unpark() calls. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5734 // See also: "Semaphores in Plan 9" by Mullender & Cox |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5735 // |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5736 // Note: Forcing a transition from "-1" to "1" on an unpark() means |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5737 // that it will take two back-to-back park() calls for the owning |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5738 // thread to block. This has the benefit of forcing a spurious return |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5739 // from the first park() call after an unpark() call which will help |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5740 // shake out uses of park() and unpark() without condition variables. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5741 |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5742 if (Atomic::xchg(1, &_Event) >= 0) return; |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5743 |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5744 // Wait for the thread associated with the event to vacate |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5745 int status = pthread_mutex_lock(_mutex); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5746 assert_status(status == 0, status, "mutex_lock"); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5747 int AnyWaiters = _nParked; |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5748 assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant"); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5749 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) { |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5750 AnyWaiters = 0; |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5751 pthread_cond_signal(_cond); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5752 } |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5753 status = pthread_mutex_unlock(_mutex); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5754 assert_status(status == 0, status, "mutex_unlock"); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5755 if (AnyWaiters != 0) { |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5756 status = pthread_cond_signal(_cond); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5757 assert_status(status == 0, status, "cond_signal"); |
0 | 5758 } |
5759 | |
5760 // Note that we signal() _after dropping the lock for "immortal" Events. | |
5761 // This is safe and avoids a common class of futile wakeups. In rare | |
5762 // circumstances this can cause a thread to return prematurely from | |
5763 // cond_{timed}wait() but the spurious wakeup is benign and the victim will | |
5764 // simply re-test the condition and re-park itself. | |
5765 } | |
5766 | |
5767 | |
5768 // JSR166 | |
5769 // ------------------------------------------------------- | |
5770 | |
5771 /* | |
5772 * The solaris and linux implementations of park/unpark are fairly | |
5773 * conservative for now, but can be improved. They currently use a | |
5774 * mutex/condvar pair, plus a a count. | |
5775 * Park decrements count if > 0, else does a condvar wait. Unpark | |
5776 * sets count to 1 and signals condvar. Only one thread ever waits | |
5777 * on the condvar. Contention seen when trying to park implies that someone | |
5778 * is unparking you, so don't wait. And spurious returns are fine, so there | |
5779 * is no need to track notifications. | |
5780 */ | |
5781 | |
5782 #define MAX_SECS 100000000 | |
5783 /* | |
5784 * This code is common to linux and solaris and will be moved to a | |
5785 * common place in dolphin. | |
5786 * | |
5787 * The passed in time value is either a relative time in nanoseconds | |
5788 * or an absolute time in milliseconds. Either way it has to be unpacked | |
5789 * into suitable seconds and nanoseconds components and stored in the | |
5790 * given timespec structure. | |
5791 * Given time is a 64-bit value and the time_t used in the timespec is only | |
5792 * a signed-32-bit value (except on 64-bit Linux) we have to watch for | |
5793 * overflow if times way in the future are given. Further on Solaris versions | |
5794 * prior to 10 there is a restriction (see cond_timedwait) that the specified | |
5795 * number of seconds, in abstime, is less than current_time + 100,000,000. | |
5796 * As it will be 28 years before "now + 100000000" will overflow we can | |
5797 * ignore overflow and just impose a hard-limit on seconds using the value | |
5798 * of "now + 100,000,000". This places a limit on the timeout of about 3.17 | |
5799 * years from "now". | |
5800 */ | |
5801 | |
5802 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { | |
5803 assert (time > 0, "convertTime"); | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5804 time_t max_secs = 0; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5805 |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5806 if (!os::Linux::supports_monotonic_clock() || isAbsolute) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5807 struct timeval now; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5808 int status = gettimeofday(&now, NULL); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5809 assert(status == 0, "gettimeofday"); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5810 |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5811 max_secs = now.tv_sec + MAX_SECS; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5812 |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5813 if (isAbsolute) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5814 jlong secs = time / 1000; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5815 if (secs > max_secs) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5816 absTime->tv_sec = max_secs; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5817 } else { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5818 absTime->tv_sec = secs; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5819 } |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5820 absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5821 } else { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5822 jlong secs = time / NANOSECS_PER_SEC; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5823 if (secs >= MAX_SECS) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5824 absTime->tv_sec = max_secs; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5825 absTime->tv_nsec = 0; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5826 } else { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5827 absTime->tv_sec = now.tv_sec + secs; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5828 absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5829 if (absTime->tv_nsec >= NANOSECS_PER_SEC) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5830 absTime->tv_nsec -= NANOSECS_PER_SEC; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5831 ++absTime->tv_sec; // note: this must be <= max_secs |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5832 } |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5833 } |
0 | 5834 } |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5835 } else { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5836 // must be relative using monotonic clock |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5837 struct timespec now; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5838 int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5839 assert_status(status == 0, status, "clock_gettime"); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5840 max_secs = now.tv_sec + MAX_SECS; |
0 | 5841 jlong secs = time / NANOSECS_PER_SEC; |
5842 if (secs >= MAX_SECS) { | |
5843 absTime->tv_sec = max_secs; | |
5844 absTime->tv_nsec = 0; | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5845 } else { |
0 | 5846 absTime->tv_sec = now.tv_sec + secs; |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5847 absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_nsec; |
0 | 5848 if (absTime->tv_nsec >= NANOSECS_PER_SEC) { |
5849 absTime->tv_nsec -= NANOSECS_PER_SEC; | |
5850 ++absTime->tv_sec; // note: this must be <= max_secs | |
5851 } | |
5852 } | |
5853 } | |
5854 assert(absTime->tv_sec >= 0, "tv_sec < 0"); | |
5855 assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs"); | |
5856 assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); | |
5857 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); | |
5858 } | |
5859 | |
5860 void Parker::park(bool isAbsolute, jlong time) { | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5861 // Ideally we'd do something useful while spinning, such |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5862 // as calling unpackTime(). |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5863 |
0 | 5864 // Optional fast-path check: |
5865 // Return immediately if a permit is available. | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5866 // We depend on Atomic::xchg() having full barrier semantics |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5867 // since we are doing a lock-free update to _counter. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5868 if (Atomic::xchg(0, &_counter) > 0) return; |
0 | 5869 |
5870 Thread* thread = Thread::current(); | |
5871 assert(thread->is_Java_thread(), "Must be JavaThread"); | |
5872 JavaThread *jt = (JavaThread *)thread; | |
5873 | |
5874 // Optional optimization -- avoid state transitions if there's an interrupt pending. | |
5875 // Check interrupt before trying to wait | |
5876 if (Thread::is_interrupted(thread, false)) { | |
5877 return; | |
5878 } | |
5879 | |
5880 // Next, demultiplex/decode time arguments | |
5881 timespec absTime; | |
1865
1c352af0135d
6763959: java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
acorn
parents:
1750
diff
changeset
|
5882 if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all |
0 | 5883 return; |
5884 } | |
5885 if (time > 0) { | |
5886 unpackTime(&absTime, isAbsolute, time); | |
5887 } | |
5888 | |
5889 | |
5890 // Enter safepoint region | |
5891 // Beware of deadlocks such as 6317397. | |
5892 // The per-thread Parker:: mutex is a classic leaf-lock. | |
5893 // In particular a thread must never block on the Threads_lock while | |
5894 // holding the Parker:: mutex. If safepoints are pending both the | |
5895 // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock. | |
5896 ThreadBlockInVM tbivm(jt); | |
5897 | |
5898 // Don't wait if cannot get lock since interference arises from | |
5899 // unblocking. Also. check interrupt before trying wait | |
5900 if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) { | |
5901 return; | |
5902 } | |
5903 | |
5904 int status ; | |
5905 if (_counter > 0) { // no wait needed | |
5906 _counter = 0; | |
5907 status = pthread_mutex_unlock(_mutex); | |
5908 assert (status == 0, "invariant") ; | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5909 // Paranoia to ensure our locked and lock-free paths interact |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5910 // correctly with each other and Java-level accesses. |
1117
95e9083cf4a7
6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents:
1010
diff
changeset
|
5911 OrderAccess::fence(); |
0 | 5912 return; |
5913 } | |
5914 | |
5915 #ifdef ASSERT | |
5916 // Don't catch signals while blocked; let the running threads have the signals. | |
5917 // (This allows a debugger to break into the running thread.) | |
5918 sigset_t oldsigs; | |
5919 sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals(); | |
5920 pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs); | |
5921 #endif | |
5922 | |
5923 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); | |
5924 jt->set_suspend_equivalent(); | |
5925 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() | |
5926 | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5927 assert(_cur_index == -1, "invariant"); |
0 | 5928 if (time == 0) { |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5929 _cur_index = REL_INDEX; // arbitrary choice when not timed |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5930 status = pthread_cond_wait (&_cond[_cur_index], _mutex) ; |
0 | 5931 } else { |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5932 _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5933 status = os::Linux::safe_cond_timedwait (&_cond[_cur_index], _mutex, &absTime) ; |
0 | 5934 if (status != 0 && WorkAroundNPTLTimedWaitHang) { |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5935 pthread_cond_destroy (&_cond[_cur_index]) ; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5936 pthread_cond_init (&_cond[_cur_index], isAbsolute ? NULL : os::Linux::condAttr()); |
0 | 5937 } |
5938 } | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5939 _cur_index = -1; |
0 | 5940 assert_status(status == 0 || status == EINTR || |
5941 status == ETIME || status == ETIMEDOUT, | |
5942 status, "cond_timedwait"); | |
5943 | |
5944 #ifdef ASSERT | |
5945 pthread_sigmask(SIG_SETMASK, &oldsigs, NULL); | |
5946 #endif | |
5947 | |
5948 _counter = 0 ; | |
5949 status = pthread_mutex_unlock(_mutex) ; | |
5950 assert_status(status == 0, status, "invariant") ; | |
7629
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5951 // Paranoia to ensure our locked and lock-free paths interact |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5952 // correctly with each other and Java-level accesses. |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5953 OrderAccess::fence(); |
22ba8c8ce6a6
8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents:
7456
diff
changeset
|
5954 |
0 | 5955 // If externally suspended while waiting, re-suspend |
5956 if (jt->handle_special_suspend_equivalent_condition()) { | |
5957 jt->java_suspend_self(); | |
5958 } | |
5959 } | |
5960 | |
5961 void Parker::unpark() { | |
5962 int s, status ; | |
5963 status = pthread_mutex_lock(_mutex); | |
5964 assert (status == 0, "invariant") ; | |
5965 s = _counter; | |
5966 _counter = 1; | |
5967 if (s < 1) { | |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5968 // thread might be parked |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5969 if (_cur_index != -1) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5970 // thread is definitely parked |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5971 if (WorkAroundNPTLTimedWaitHang) { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5972 status = pthread_cond_signal (&_cond[_cur_index]); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5973 assert (status == 0, "invariant"); |
0 | 5974 status = pthread_mutex_unlock(_mutex); |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5975 assert (status == 0, "invariant"); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5976 } else { |
0 | 5977 status = pthread_mutex_unlock(_mutex); |
12211
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5978 assert (status == 0, "invariant"); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5979 status = pthread_cond_signal (&_cond[_cur_index]); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5980 assert (status == 0, "invariant"); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5981 } |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5982 } else { |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5983 pthread_mutex_unlock(_mutex); |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5984 assert (status == 0, "invariant") ; |
2e6938dd68f2
6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents:
12182
diff
changeset
|
5985 } |
0 | 5986 } else { |
5987 pthread_mutex_unlock(_mutex); | |
5988 assert (status == 0, "invariant") ; | |
5989 } | |
5990 } | |
5991 | |
5992 | |
5993 extern char** environ; | |
5994 | |
5995 #ifndef __NR_fork | |
5996 #define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57) | |
5997 #endif | |
5998 | |
5999 #ifndef __NR_execve | |
6000 #define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59) | |
6001 #endif | |
6002 | |
6003 // Run the specified command in a separate process. Return its exit value, | |
6004 // or -1 on failure (e.g. can't fork a new process). | |
6005 // Unlike system(), this function can be called from signal handler. It | |
6006 // doesn't block SIGINT et al. | |
6007 int os::fork_and_exec(char* cmd) { | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
6008 const char * argv[4] = {"sh", "-c", cmd, NULL}; |
0 | 6009 |
6010 // fork() in LinuxThreads/NPTL is not async-safe. It needs to run | |
6011 // pthread_atfork handlers and reset pthread library. All we need is a | |
6012 // separate process to execve. Make a direct syscall to fork process. | |
6013 // On IA64 there's no fork syscall, we have to use fork() and hope for | |
6014 // the best... | |
6015 pid_t pid = NOT_IA64(syscall(__NR_fork);) | |
6016 IA64_ONLY(fork();) | |
6017 | |
6018 if (pid < 0) { | |
6019 // fork failed | |
6020 return -1; | |
6021 | |
6022 } else if (pid == 0) { | |
6023 // child process | |
6024 | |
6025 // execve() in LinuxThreads will call pthread_kill_other_threads_np() | |
6026 // first to kill every thread on the thread list. Because this list is | |
6027 // not reset by fork() (see notes above), execve() will instead kill | |
6028 // every thread in the parent process. We know this is the only thread | |
6029 // in the new process, so make a system call directly. | |
6030 // IA64 should use normal execve() from glibc to match the glibc fork() | |
6031 // above. | |
6032 NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);) | |
199
f139919897d2
6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents:
141
diff
changeset
|
6033 IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);) |
0 | 6034 |
6035 // execve failed | |
6036 _exit(-1); | |
6037 | |
6038 } else { | |
6039 // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't | |
6040 // care about the actual exit code, for now. | |
6041 | |
6042 int status; | |
6043 | |
6044 // Wait for the child process to exit. This returns immediately if | |
6045 // the child has already exited. */ | |
6046 while (waitpid(pid, &status, 0) < 0) { | |
6047 switch (errno) { | |
6048 case ECHILD: return 0; | |
6049 case EINTR: break; | |
6050 default: return -1; | |
6051 } | |
6052 } | |
6053 | |
6054 if (WIFEXITED(status)) { | |
6055 // The child exited normally; get its exit code. | |
6056 return WEXITSTATUS(status); | |
6057 } else if (WIFSIGNALED(status)) { | |
6058 // The child exited because of a signal | |
6059 // The best value to return is 0x80 + signal number, | |
6060 // because that is what all Unix shells do, and because | |
6061 // it allows callers to distinguish between process exit and | |
6062 // process death by signal. | |
6063 return 0x80 + WTERMSIG(status); | |
6064 } else { | |
6065 // Unknown exit code; pass it through | |
6066 return status; | |
6067 } | |
6068 } | |
6069 } | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6070 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6071 // is_headless_jre() |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6072 // |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
6073 // Test for the existence of xawt/libmawt.so or libawt_xawt.so |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6074 // in order to report if we are running in a headless jre |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6075 // |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
6076 // 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
|
6077 // 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
|
6078 // |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6079 bool os::is_headless_jre() { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6080 struct stat statbuf; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6081 char buf[MAXPATHLEN]; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6082 char libmawtpath[MAXPATHLEN]; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6083 const char *xawtstr = "/xawt/libmawt.so"; |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
6084 const char *new_xawtstr = "/libawt_xawt.so"; |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6085 char *p; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6086 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6087 // Get path to libjvm.so |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6088 os::jvm_path(buf, sizeof(buf)); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6089 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6090 // Get rid of libjvm.so |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6091 p = strrchr(buf, '/'); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6092 if (p == NULL) return false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6093 else *p = '\0'; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6094 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6095 // Get rid of client or server |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6096 p = strrchr(buf, '/'); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6097 if (p == NULL) return false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6098 else *p = '\0'; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6099 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6100 // check xawt/libmawt.so |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6101 strcpy(libmawtpath, buf); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6102 strcat(libmawtpath, xawtstr); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6103 if (::stat(libmawtpath, &statbuf) == 0) return false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6104 |
4082
36b057451829
7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents:
4006
diff
changeset
|
6105 // check libawt_xawt.so |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6106 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
|
6107 strcat(libmawtpath, new_xawtstr); |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6108 if (::stat(libmawtpath, &statbuf) == 0) return false; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6109 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6110 return true; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6111 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1642
diff
changeset
|
6112 |
6200
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6113 // Get the default path to the core file |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6114 // Returns the length of the string |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6115 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
|
6116 const char* p = get_current_directory(buffer, bufferSize); |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6117 |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6118 if (p == NULL) { |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6119 assert(p != NULL, "failed to get current directory"); |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6120 return 0; |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6121 } |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6122 |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6123 return strlen(buffer); |
65906dc96aa1
7129724: MAC: Core file location is wrong in crash report
mikael
parents:
6197
diff
changeset
|
6124 } |
3802
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6125 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6126 #ifdef JAVASE_EMBEDDED |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6127 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6128 // A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory. |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6129 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6130 MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6131 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6132 // ctor |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6133 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6134 MemNotifyThread::MemNotifyThread(int fd): Thread() { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6135 assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread"); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6136 _fd = fd; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6137 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6138 if (os::create_thread(this, os::os_thread)) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6139 _memnotify_thread = this; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6140 os::set_priority(this, NearMaxPriority); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6141 os::start_thread(this); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6142 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6143 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6144 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6145 // Where all the work gets done |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6146 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6147 void MemNotifyThread::run() { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6148 assert(this == memnotify_thread(), "expected the singleton MemNotifyThread"); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6149 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6150 // Set up the select arguments |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6151 fd_set rfds; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6152 if (_fd != -1) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6153 FD_ZERO(&rfds); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6154 FD_SET(_fd, &rfds); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6155 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6156 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6157 // Now wait for the mem_notify device to wake up |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6158 while (1) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6159 // Wait for the mem_notify device to signal us.. |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6160 int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6161 if (rc == -1) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6162 perror("select!\n"); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6163 break; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6164 } else if (rc) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6165 //ssize_t free_before = os::available_memory(); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6166 //tty->print ("Notified: Free: %dK \n",os::available_memory()/1024); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6167 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6168 // The kernel is telling us there is not much memory left... |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6169 // try to do something about that |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6170 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6171 // If we are not already in a GC, try one. |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6172 if (!Universe::heap()->is_gc_active()) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6173 Universe::heap()->collect(GCCause::_allocation_failure); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6174 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6175 //ssize_t free_after = os::available_memory(); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6176 //tty->print ("Post-Notify: Free: %dK\n",free_after/1024); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6177 //tty->print ("GC freed: %dK\n", (free_after - free_before)/1024); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6178 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6179 // We might want to do something like the following if we find the GC's are not helping... |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6180 // Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6181 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6182 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6183 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6184 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6185 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6186 // See if the /dev/mem_notify device exists, and if so, start a thread to monitor it. |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6187 // |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6188 void MemNotifyThread::start() { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6189 int fd; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6190 fd = open ("/dev/mem_notify", O_RDONLY, 0); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6191 if (fd < 0) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6192 return; |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6193 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6194 |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6195 if (memnotify_thread() == NULL) { |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6196 new MemNotifyThread(fd); |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6197 } |
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6198 } |
10405 | 6199 |
3802
b0b8491925fe
7061212: use o/s low memory notification in embedded builds
jcoomes
parents:
3800
diff
changeset
|
6200 #endif // JAVASE_EMBEDDED |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6201 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6202 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6203 /////////////// Unit tests /////////////// |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6204 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6205 #ifndef PRODUCT |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6206 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6207 #define test_log(...) \ |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6208 do {\ |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6209 if (VerboseInternalVMTests) { \ |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6210 tty->print_cr(__VA_ARGS__); \ |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6211 tty->flush(); \ |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6212 }\ |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6213 } while (false) |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6214 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6215 class TestReserveMemorySpecial : AllStatic { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6216 public: |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6217 static void small_page_write(void* addr, size_t size) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6218 size_t page_size = os::vm_page_size(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6219 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6220 char* end = (char*)addr + size; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6221 for (char* p = (char*)addr; p < end; p += page_size) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6222 *p = 1; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6223 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6224 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6225 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6226 static void test_reserve_memory_special_huge_tlbfs_only(size_t size) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6227 if (!UseHugeTLBFS) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6228 return; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6229 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6230 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6231 test_log("test_reserve_memory_special_huge_tlbfs_only(" SIZE_FORMAT ")", size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6232 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6233 char* addr = os::Linux::reserve_memory_special_huge_tlbfs_only(size, NULL, false); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6234 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6235 if (addr != NULL) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6236 small_page_write(addr, size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6237 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6238 os::Linux::release_memory_special_huge_tlbfs(addr, size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6239 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6240 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6241 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6242 static void test_reserve_memory_special_huge_tlbfs_only() { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6243 if (!UseHugeTLBFS) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6244 return; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6245 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6246 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6247 size_t lp = os::large_page_size(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6248 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6249 for (size_t size = lp; size <= lp * 10; size += lp) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6250 test_reserve_memory_special_huge_tlbfs_only(size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6251 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6252 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6253 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6254 static void test_reserve_memory_special_huge_tlbfs_mixed(size_t size, size_t alignment) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6255 if (!UseHugeTLBFS) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6256 return; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6257 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6258 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6259 test_log("test_reserve_memory_special_huge_tlbfs_mixed(" SIZE_FORMAT ", " SIZE_FORMAT ")", |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6260 size, alignment); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6261 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6262 assert(size >= os::large_page_size(), "Incorrect input to test"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6263 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6264 char* addr = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, NULL, false); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6265 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6266 if (addr != NULL) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6267 small_page_write(addr, size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6268 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6269 os::Linux::release_memory_special_huge_tlbfs(addr, size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6270 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6271 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6272 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6273 static void test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(size_t size) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6274 size_t lp = os::large_page_size(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6275 size_t ag = os::vm_allocation_granularity(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6276 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6277 for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6278 test_reserve_memory_special_huge_tlbfs_mixed(size, alignment); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6279 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6280 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6281 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6282 static void test_reserve_memory_special_huge_tlbfs_mixed() { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6283 size_t lp = os::large_page_size(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6284 size_t ag = os::vm_allocation_granularity(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6285 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6286 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6287 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + ag); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6288 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + lp / 2); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6289 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6290 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + ag); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6291 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 - ag); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6292 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + lp / 2); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6293 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6294 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10 + lp / 2); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6295 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6296 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6297 static void test_reserve_memory_special_huge_tlbfs() { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6298 if (!UseHugeTLBFS) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6299 return; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6300 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6301 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6302 test_reserve_memory_special_huge_tlbfs_only(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6303 test_reserve_memory_special_huge_tlbfs_mixed(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6304 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6305 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6306 static void test_reserve_memory_special_shm(size_t size, size_t alignment) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6307 if (!UseSHM) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6308 return; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6309 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6310 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6311 test_log("test_reserve_memory_special_shm(" SIZE_FORMAT ", " SIZE_FORMAT ")", size, alignment); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6312 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6313 char* addr = os::Linux::reserve_memory_special_shm(size, alignment, NULL, false); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6314 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6315 if (addr != NULL) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6316 assert(is_ptr_aligned(addr, alignment), "Check"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6317 assert(is_ptr_aligned(addr, os::large_page_size()), "Check"); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6318 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6319 small_page_write(addr, size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6320 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6321 os::Linux::release_memory_special_shm(addr, size); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6322 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6323 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6324 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6325 static void test_reserve_memory_special_shm() { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6326 size_t lp = os::large_page_size(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6327 size_t ag = os::vm_allocation_granularity(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6328 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6329 for (size_t size = ag; size < lp * 3; size += ag) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6330 for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6331 test_reserve_memory_special_shm(size, alignment); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6332 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6333 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6334 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6335 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6336 static void test() { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6337 test_reserve_memory_special_huge_tlbfs(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6338 test_reserve_memory_special_shm(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6339 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6340 }; |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6341 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6342 void TestReserveMemorySpecial_test() { |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6343 TestReserveMemorySpecial::test(); |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6344 } |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6345 |
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
11092
diff
changeset
|
6346 #endif |