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