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