annotate src/os/linux/vm/os_linux.cpp @ 3598:9fe4191f46af

IdealGraphVisualizer: Try to resolve UI concurrency issues by introducing locking for the list of graphs in Group and adding graphs to their group only after they have been fully read in.
author Peter Hofer <peter.hofer@jku.at>
date Wed, 19 Oct 2011 17:49:28 +0200
parents be4ca325525a
children 04b9a2566eec
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2204
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
25 # define __STDC_FORMAT_MACROS
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
26
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
27 // no precompiled headers
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
28 #include "classfile/classLoader.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
29 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
30 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
31 #include "code/icBuffer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
32 #include "code/vtableStubs.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
33 #include "compiler/compileBroker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
34 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
35 #include "jvm_linux.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
36 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
37 #include "memory/filemap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
38 #include "mutex_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
39 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
40 #include "os_share_linux.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
41 #include "prims/jniFastGetField.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
42 #include "prims/jvm.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
43 #include "prims/jvm_misc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
44 #include "runtime/arguments.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
45 #include "runtime/extendedPC.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
46 #include "runtime/globals.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
47 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
48 #include "runtime/java.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
49 #include "runtime/javaCalls.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
50 #include "runtime/mutexLocker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
51 #include "runtime/objectMonitor.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
52 #include "runtime/osThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
53 #include "runtime/perfMemory.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
54 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
55 #include "runtime/statSampler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
56 #include "runtime/stubRoutines.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
57 #include "runtime/threadCritical.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
58 #include "runtime/timer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
59 #include "services/attachListener.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
60 #include "services/runtimeService.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
61 #include "thread_linux.inline.hpp"
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
62 #include "utilities/decoder.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
63 #include "utilities/defaultStream.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
64 #include "utilities/events.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
65 #include "utilities/growableArray.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
66 #include "utilities/vmError.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
67 #ifdef TARGET_ARCH_x86
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
68 # include "assembler_x86.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
69 # include "nativeInst_x86.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
70 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
71 #ifdef TARGET_ARCH_sparc
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
72 # include "assembler_sparc.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
73 # include "nativeInst_sparc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
74 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
75 #ifdef TARGET_ARCH_zero
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
76 # include "assembler_zero.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
77 # include "nativeInst_zero.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
78 #endif
2192
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2130
diff changeset
79 #ifdef TARGET_ARCH_arm
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2130
diff changeset
80 # include "assembler_arm.inline.hpp"
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2130
diff changeset
81 # include "nativeInst_arm.hpp"
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2130
diff changeset
82 #endif
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2130
diff changeset
83 #ifdef TARGET_ARCH_ppc
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2130
diff changeset
84 # include "assembler_ppc.inline.hpp"
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2130
diff changeset
85 # include "nativeInst_ppc.hpp"
b92c45f2bc75 7016023: Enable building ARM and PPC from src/closed repository
bobv
parents: 2130
diff changeset
86 #endif
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
87 #ifdef COMPILER1
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
88 #include "c1/c1_Runtime1.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
89 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
90 #ifdef COMPILER2
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
91 #include "opto/runtime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
92 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // put OS-includes here
a61af66fc99e Initial load
duke
parents:
diff changeset
95 # include <sys/types.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
96 # include <sys/mman.h>
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
97 # include <sys/stat.h>
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
98 # include <sys/select.h>
0
a61af66fc99e Initial load
duke
parents:
diff changeset
99 # include <pthread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
100 # include <signal.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
101 # include <errno.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
102 # include <dlfcn.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
103 # include <stdio.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
104 # include <unistd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
105 # include <sys/resource.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
106 # include <pthread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
107 # include <sys/stat.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
108 # include <sys/time.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
109 # include <sys/times.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
110 # include <sys/utsname.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
111 # include <sys/socket.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
112 # include <sys/wait.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
113 # include <pwd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
114 # include <poll.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
115 # include <semaphore.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
116 # include <fcntl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
117 # include <string.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
118 # include <syscall.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
119 # include <sys/sysinfo.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
120 # include <gnu/libc-version.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
121 # include <sys/ipc.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
122 # include <sys/shm.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
123 # include <link.h>
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
124 # include <stdint.h>
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
125 # include <inttypes.h>
2033
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
126 # include <sys/ioctl.h>
0
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 #define MAX_PATH (2 * K)
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 // for timer info max values which include all bits
a61af66fc99e Initial load
duke
parents:
diff changeset
131 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
a61af66fc99e Initial load
duke
parents:
diff changeset
132 #define SEC_IN_NANOSECS 1000000000LL
a61af66fc99e Initial load
duke
parents:
diff changeset
133
2204
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
134 #define LARGEPAGES_BIT (1 << 6)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
135 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // global variables
a61af66fc99e Initial load
duke
parents:
diff changeset
137 julong os::Linux::_physical_memory = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 address os::Linux::_initial_thread_stack_bottom = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
140 uintptr_t os::Linux::_initial_thread_stack_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
141
a61af66fc99e Initial load
duke
parents:
diff changeset
142 int (*os::Linux::_clock_gettime)(clockid_t, struct timespec *) = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
143 int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 Mutex* os::Linux::_createThread_lock = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
145 pthread_t os::Linux::_main_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
146 int os::Linux::_page_size = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 bool os::Linux::_is_floating_stack = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 bool os::Linux::_is_NPTL = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 bool os::Linux::_supports_fast_thread_cpu_time = false;
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
150 const char * os::Linux::_glibc_version = NULL;
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
151 const char * os::Linux::_libpthread_version = NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 static jlong initial_time_count=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 static int clock_tics_per_sec = 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 // For diagnostics to print a message once. see run_periodic_checks
a61af66fc99e Initial load
duke
parents:
diff changeset
158 static sigset_t check_signal_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 static bool check_signals = true;;
a61af66fc99e Initial load
duke
parents:
diff changeset
160
a61af66fc99e Initial load
duke
parents:
diff changeset
161 static pid_t _initial_pid = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 /* Signal number used to suspend/resume a thread */
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 /* do not use any signal number less than SIGSEGV, see 4355769 */
a61af66fc99e Initial load
duke
parents:
diff changeset
166 static int SR_signum = SIGUSR2;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 sigset_t SR_sigset;
a61af66fc99e Initial load
duke
parents:
diff changeset
168
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
169 /* Used to protect dlsym() calls */
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
170 static pthread_mutex_t dl_mutex;
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
171
0
a61af66fc99e Initial load
duke
parents:
diff changeset
172 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
173 // utility functions
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 static int SR_initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
176 static int SR_finalize();
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178 julong os::available_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 return Linux::available_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
181
a61af66fc99e Initial load
duke
parents:
diff changeset
182 julong os::Linux::available_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // values in struct sysinfo are "unsigned long"
a61af66fc99e Initial load
duke
parents:
diff changeset
184 struct sysinfo si;
a61af66fc99e Initial load
duke
parents:
diff changeset
185 sysinfo(&si);
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 return (julong)si.freeram * si.mem_unit;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 julong os::physical_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 return Linux::physical_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193
20
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
194 julong os::allocatable_physical_memory(julong size) {
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
195 #ifdef _LP64
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
196 return size;
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
197 #else
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
198 julong result = MIN2(size, (julong)3800*M);
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
199 if (!is_allocatable(result)) {
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
200 // See comments under solaris for alignment considerations
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
201 julong reasonable_size = (julong)2*G - 2 * os::vm_page_size();
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
202 result = MIN2(size, reasonable_size);
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
203 }
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
204 return result;
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
205 #endif // _LP64
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
206 }
e195fe4c40c7 6629887: 64-bit windows should not restrict default heap size to 1400m
phh
parents: 0
diff changeset
207
0
a61af66fc99e Initial load
duke
parents:
diff changeset
208 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // environment support
a61af66fc99e Initial load
duke
parents:
diff changeset
210
a61af66fc99e Initial load
duke
parents:
diff changeset
211 bool os::getenv(const char* name, char* buf, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 const char* val = ::getenv(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 if (val != NULL && strlen(val) < (size_t)len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 strcpy(buf, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
215 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if (len > 0) buf[0] = 0; // return a null string
a61af66fc99e Initial load
duke
parents:
diff changeset
218 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221
a61af66fc99e Initial load
duke
parents:
diff changeset
222 // Return true if user is running as root.
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224 bool os::have_special_privileges() {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 static bool init = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 static bool privileges = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
227 if (!init) {
a61af66fc99e Initial load
duke
parents:
diff changeset
228 privileges = (getuid() != geteuid()) || (getgid() != getegid());
a61af66fc99e Initial load
duke
parents:
diff changeset
229 init = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 return privileges;
a61af66fc99e Initial load
duke
parents:
diff changeset
232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
233
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 #ifndef SYS_gettid
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // i386: 224, ia64: 1105, amd64: 186, sparc 143
a61af66fc99e Initial load
duke
parents:
diff changeset
237 #ifdef __ia64__
a61af66fc99e Initial load
duke
parents:
diff changeset
238 #define SYS_gettid 1105
a61af66fc99e Initial load
duke
parents:
diff changeset
239 #elif __i386__
a61af66fc99e Initial load
duke
parents:
diff changeset
240 #define SYS_gettid 224
a61af66fc99e Initial load
duke
parents:
diff changeset
241 #elif __amd64__
a61af66fc99e Initial load
duke
parents:
diff changeset
242 #define SYS_gettid 186
a61af66fc99e Initial load
duke
parents:
diff changeset
243 #elif __sparc__
a61af66fc99e Initial load
duke
parents:
diff changeset
244 #define SYS_gettid 143
a61af66fc99e Initial load
duke
parents:
diff changeset
245 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
246 #error define gettid for the arch
a61af66fc99e Initial load
duke
parents:
diff changeset
247 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
248 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
249
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // Cpu architecture string
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
251 #if defined(ZERO)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
252 static char cpu_arch[] = ZERO_LIBARCH;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
253 #elif defined(IA64)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
254 static char cpu_arch[] = "ia64";
a61af66fc99e Initial load
duke
parents:
diff changeset
255 #elif defined(IA32)
a61af66fc99e Initial load
duke
parents:
diff changeset
256 static char cpu_arch[] = "i386";
a61af66fc99e Initial load
duke
parents:
diff changeset
257 #elif defined(AMD64)
a61af66fc99e Initial load
duke
parents:
diff changeset
258 static char cpu_arch[] = "amd64";
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
259 #elif defined(ARM)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
260 static char cpu_arch[] = "arm";
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
261 #elif defined(PPC)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
262 static char cpu_arch[] = "ppc";
0
a61af66fc99e Initial load
duke
parents:
diff changeset
263 #elif defined(SPARC)
a61af66fc99e Initial load
duke
parents:
diff changeset
264 # ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
265 static char cpu_arch[] = "sparcv9";
a61af66fc99e Initial load
duke
parents:
diff changeset
266 # else
a61af66fc99e Initial load
duke
parents:
diff changeset
267 static char cpu_arch[] = "sparc";
a61af66fc99e Initial load
duke
parents:
diff changeset
268 # endif
a61af66fc99e Initial load
duke
parents:
diff changeset
269 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
270 #error Add appropriate cpu_arch setting
a61af66fc99e Initial load
duke
parents:
diff changeset
271 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
272
a61af66fc99e Initial load
duke
parents:
diff changeset
273
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // pid_t gettid()
a61af66fc99e Initial load
duke
parents:
diff changeset
275 //
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // Returns the kernel thread id of the currently running thread. Kernel
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // thread id is used to access /proc.
a61af66fc99e Initial load
duke
parents:
diff changeset
278 //
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // (Note that getpid() on LinuxThreads returns kernel thread id too; but
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // on NPTL, it returns the same pid for all threads, as required by POSIX.)
a61af66fc99e Initial load
duke
parents:
diff changeset
281 //
a61af66fc99e Initial load
duke
parents:
diff changeset
282 pid_t os::Linux::gettid() {
a61af66fc99e Initial load
duke
parents:
diff changeset
283 int rslt = syscall(SYS_gettid);
a61af66fc99e Initial load
duke
parents:
diff changeset
284 if (rslt == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // old kernel, no NPTL support
a61af66fc99e Initial load
duke
parents:
diff changeset
286 return getpid();
a61af66fc99e Initial load
duke
parents:
diff changeset
287 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 return (pid_t)rslt;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292 // Most versions of linux have a bug where the number of processors are
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // determined by looking at the /proc file system. In a chroot environment,
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // the system call returns 1. This causes the VM to act as if it is
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // a single processor and elide locking (see is_MP() call).
a61af66fc99e Initial load
duke
parents:
diff changeset
296 static bool unsafe_chroot_detected = false;
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
297 static const char *unstable_chroot_error = "/proc file system not found.\n"
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
298 "Java may be unstable running multithreaded in a chroot "
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
299 "environment on Linux when /proc filesystem is not mounted.";
0
a61af66fc99e Initial load
duke
parents:
diff changeset
300
a61af66fc99e Initial load
duke
parents:
diff changeset
301 void os::Linux::initialize_system_info() {
1123
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 1117
diff changeset
302 set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 1117
diff changeset
303 if (processor_count() == 1) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
304 pid_t pid = os::Linux::gettid();
a61af66fc99e Initial load
duke
parents:
diff changeset
305 char fname[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
306 jio_snprintf(fname, sizeof(fname), "/proc/%d", pid);
a61af66fc99e Initial load
duke
parents:
diff changeset
307 FILE *fp = fopen(fname, "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
308 if (fp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
309 unsafe_chroot_detected = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
310 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
311 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
314 _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
1123
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 1117
diff changeset
315 assert(processor_count() > 0, "linux error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
317
a61af66fc99e Initial load
duke
parents:
diff changeset
318 void os::init_system_properties_values() {
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // char arch[12];
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // sysinfo(SI_ARCHITECTURE, arch, sizeof(arch));
a61af66fc99e Initial load
duke
parents:
diff changeset
321
a61af66fc99e Initial load
duke
parents:
diff changeset
322 // The next steps are taken in the product version:
a61af66fc99e Initial load
duke
parents:
diff changeset
323 //
a61af66fc99e Initial load
duke
parents:
diff changeset
324 // Obtain the JAVA_HOME value from the location of libjvm[_g].so.
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // This library should be located at:
a61af66fc99e Initial load
duke
parents:
diff changeset
326 // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm[_g].so.
a61af66fc99e Initial load
duke
parents:
diff changeset
327 //
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // If "/jre/lib/" appears at the right place in the path, then we
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // assume libjvm[_g].so is installed in a JDK and we use this path.
a61af66fc99e Initial load
duke
parents:
diff changeset
330 //
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // Otherwise exit with message: "Could not create the Java virtual machine."
a61af66fc99e Initial load
duke
parents:
diff changeset
332 //
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // The following extra steps are taken in the debugging version:
a61af66fc99e Initial load
duke
parents:
diff changeset
334 //
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // If "/jre/lib/" does NOT appear at the right place in the path
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // instead of exit check for $JAVA_HOME environment variable.
a61af66fc99e Initial load
duke
parents:
diff changeset
337 //
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // it looks like libjvm[_g].so is installed there
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm[_g].so.
a61af66fc99e Initial load
duke
parents:
diff changeset
342 //
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // Otherwise exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
344 //
a61af66fc99e Initial load
duke
parents:
diff changeset
345 // Important note: if the location of libjvm.so changes this
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // code needs to be changed accordingly.
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // The next few definitions allow the code to be verbatim:
a61af66fc99e Initial load
duke
parents:
diff changeset
349 #define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n))
a61af66fc99e Initial load
duke
parents:
diff changeset
350 #define getenv(n) ::getenv(n)
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
353 * See ld(1):
a61af66fc99e Initial load
duke
parents:
diff changeset
354 * The linker uses the following search paths to locate required
a61af66fc99e Initial load
duke
parents:
diff changeset
355 * shared libraries:
a61af66fc99e Initial load
duke
parents:
diff changeset
356 * 1: ...
a61af66fc99e Initial load
duke
parents:
diff changeset
357 * ...
a61af66fc99e Initial load
duke
parents:
diff changeset
358 * 7: The default directories, normally /lib and /usr/lib.
a61af66fc99e Initial load
duke
parents:
diff changeset
359 */
509
9656bebe85a7 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 477
diff changeset
360 #if defined(AMD64) || defined(_LP64) && (defined(SPARC) || defined(PPC) || defined(S390))
9656bebe85a7 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 477
diff changeset
361 #define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib"
9656bebe85a7 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 477
diff changeset
362 #else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
363 #define DEFAULT_LIBPATH "/lib:/usr/lib"
509
9656bebe85a7 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 477
diff changeset
364 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 #define EXTENSIONS_DIR "/lib/ext"
a61af66fc99e Initial load
duke
parents:
diff changeset
367 #define ENDORSED_DIR "/lib/endorsed"
a61af66fc99e Initial load
duke
parents:
diff changeset
368 #define REG_DIR "/usr/java/packages"
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370 {
a61af66fc99e Initial load
duke
parents:
diff changeset
371 /* sysclasspath, java_home, dll_dir */
a61af66fc99e Initial load
duke
parents:
diff changeset
372 {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 char *home_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
374 char *dll_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
375 char *pslash;
a61af66fc99e Initial load
duke
parents:
diff changeset
376 char buf[MAXPATHLEN];
a61af66fc99e Initial load
duke
parents:
diff changeset
377 os::jvm_path(buf, sizeof(buf));
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // Found the full path to libjvm.so.
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // Now cut the path to <java_home>/jre if we can.
a61af66fc99e Initial load
duke
parents:
diff changeset
381 *(strrchr(buf, '/')) = '\0'; /* get rid of /libjvm.so */
a61af66fc99e Initial load
duke
parents:
diff changeset
382 pslash = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
383 if (pslash != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
384 *pslash = '\0'; /* get rid of /{client|server|hotspot} */
a61af66fc99e Initial load
duke
parents:
diff changeset
385 dll_path = malloc(strlen(buf) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
386 if (dll_path == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
387 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
388 strcpy(dll_path, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
389 Arguments::set_dll_dir(dll_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 if (pslash != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 pslash = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
393 if (pslash != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 *pslash = '\0'; /* get rid of /<arch> */
a61af66fc99e Initial load
duke
parents:
diff changeset
395 pslash = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
396 if (pslash != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
397 *pslash = '\0'; /* get rid of /lib */
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 home_path = malloc(strlen(buf) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
402 if (home_path == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
403 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
404 strcpy(home_path, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
405 Arguments::set_java_home(home_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 if (!set_boot_path('/', ':'))
a61af66fc99e Initial load
duke
parents:
diff changeset
408 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
412 * Where to look for native libraries
a61af66fc99e Initial load
duke
parents:
diff changeset
413 *
a61af66fc99e Initial load
duke
parents:
diff changeset
414 * Note: Due to a legacy implementation, most of the library path
a61af66fc99e Initial load
duke
parents:
diff changeset
415 * is set in the launcher. This was to accomodate linking restrictions
a61af66fc99e Initial load
duke
parents:
diff changeset
416 * on legacy Linux implementations (which are no longer supported).
a61af66fc99e Initial load
duke
parents:
diff changeset
417 * Eventually, all the library path setting will be done here.
a61af66fc99e Initial load
duke
parents:
diff changeset
418 *
a61af66fc99e Initial load
duke
parents:
diff changeset
419 * However, to prevent the proliferation of improperly built native
a61af66fc99e Initial load
duke
parents:
diff changeset
420 * libraries, the new path component /usr/java/packages is added here.
a61af66fc99e Initial load
duke
parents:
diff changeset
421 * Eventually, all the library path setting will be done here.
a61af66fc99e Initial load
duke
parents:
diff changeset
422 */
a61af66fc99e Initial load
duke
parents:
diff changeset
423 {
a61af66fc99e Initial load
duke
parents:
diff changeset
424 char *ld_library_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
425
a61af66fc99e Initial load
duke
parents:
diff changeset
426 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
427 * Construct the invariant part of ld_library_path. Note that the
a61af66fc99e Initial load
duke
parents:
diff changeset
428 * space for the colon and the trailing null are provided by the
a61af66fc99e Initial load
duke
parents:
diff changeset
429 * nulls included by the sizeof operator (so actually we allocate
a61af66fc99e Initial load
duke
parents:
diff changeset
430 * a byte more than necessary).
a61af66fc99e Initial load
duke
parents:
diff changeset
431 */
a61af66fc99e Initial load
duke
parents:
diff changeset
432 ld_library_path = (char *) malloc(sizeof(REG_DIR) + sizeof("/lib/") +
a61af66fc99e Initial load
duke
parents:
diff changeset
433 strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH));
a61af66fc99e Initial load
duke
parents:
diff changeset
434 sprintf(ld_library_path, REG_DIR "/lib/%s:" DEFAULT_LIBPATH, cpu_arch);
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
437 * Get the user setting of LD_LIBRARY_PATH, and prepended it. It
a61af66fc99e Initial load
duke
parents:
diff changeset
438 * should always exist (until the legacy problem cited above is
a61af66fc99e Initial load
duke
parents:
diff changeset
439 * addressed).
a61af66fc99e Initial load
duke
parents:
diff changeset
440 */
a61af66fc99e Initial load
duke
parents:
diff changeset
441 char *v = getenv("LD_LIBRARY_PATH");
a61af66fc99e Initial load
duke
parents:
diff changeset
442 if (v != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 char *t = ld_library_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
444 /* That's +1 for the colon and +1 for the trailing '\0' */
a61af66fc99e Initial load
duke
parents:
diff changeset
445 ld_library_path = (char *) malloc(strlen(v) + 1 + strlen(t) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
446 sprintf(ld_library_path, "%s:%s", v, t);
a61af66fc99e Initial load
duke
parents:
diff changeset
447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
448 Arguments::set_library_path(ld_library_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
452 * Extensions directories.
a61af66fc99e Initial load
duke
parents:
diff changeset
453 *
a61af66fc99e Initial load
duke
parents:
diff changeset
454 * Note that the space for the colon and the trailing null are provided
a61af66fc99e Initial load
duke
parents:
diff changeset
455 * by the nulls included by the sizeof operator (so actually one byte more
a61af66fc99e Initial load
duke
parents:
diff changeset
456 * than necessary is allocated).
a61af66fc99e Initial load
duke
parents:
diff changeset
457 */
a61af66fc99e Initial load
duke
parents:
diff changeset
458 {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 char *buf = malloc(strlen(Arguments::get_java_home()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
460 sizeof(EXTENSIONS_DIR) + sizeof(REG_DIR) + sizeof(EXTENSIONS_DIR));
a61af66fc99e Initial load
duke
parents:
diff changeset
461 sprintf(buf, "%s" EXTENSIONS_DIR ":" REG_DIR EXTENSIONS_DIR,
a61af66fc99e Initial load
duke
parents:
diff changeset
462 Arguments::get_java_home());
a61af66fc99e Initial load
duke
parents:
diff changeset
463 Arguments::set_ext_dirs(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
464 }
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 /* Endorsed standards default directory. */
a61af66fc99e Initial load
duke
parents:
diff changeset
467 {
a61af66fc99e Initial load
duke
parents:
diff changeset
468 char * buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
469 buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR));
a61af66fc99e Initial load
duke
parents:
diff changeset
470 sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
a61af66fc99e Initial load
duke
parents:
diff changeset
471 Arguments::set_endorsed_dirs(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
472 }
a61af66fc99e Initial load
duke
parents:
diff changeset
473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
474
a61af66fc99e Initial load
duke
parents:
diff changeset
475 #undef malloc
a61af66fc99e Initial load
duke
parents:
diff changeset
476 #undef getenv
a61af66fc99e Initial load
duke
parents:
diff changeset
477 #undef EXTENSIONS_DIR
a61af66fc99e Initial load
duke
parents:
diff changeset
478 #undef ENDORSED_DIR
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // Done
a61af66fc99e Initial load
duke
parents:
diff changeset
481 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // breakpoint support
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 void os::breakpoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
488 BREAKPOINT;
a61af66fc99e Initial load
duke
parents:
diff changeset
489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
490
a61af66fc99e Initial load
duke
parents:
diff changeset
491 extern "C" void breakpoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // use debugger to set breakpoint here
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494
a61af66fc99e Initial load
duke
parents:
diff changeset
495 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // signal support
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 debug_only(static bool signal_sets_initialized = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
499 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
500
a61af66fc99e Initial load
duke
parents:
diff changeset
501 bool os::Linux::is_sig_ignored(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
502 struct sigaction oact;
a61af66fc99e Initial load
duke
parents:
diff changeset
503 sigaction(sig, (struct sigaction*)NULL, &oact);
a61af66fc99e Initial load
duke
parents:
diff changeset
504 void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
505 : CAST_FROM_FN_PTR(void*, oact.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
506 if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN))
a61af66fc99e Initial load
duke
parents:
diff changeset
507 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
508 else
a61af66fc99e Initial load
duke
parents:
diff changeset
509 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 void os::Linux::signal_sets_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 // Should also have an assertion stating we are still single-threaded.
a61af66fc99e Initial load
duke
parents:
diff changeset
514 assert(!signal_sets_initialized, "Already initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
515 // Fill in signals that are necessarily unblocked for all threads in
a61af66fc99e Initial load
duke
parents:
diff changeset
516 // the VM. Currently, we unblock the following signals:
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // by -Xrs (=ReduceSignalUsage));
a61af66fc99e Initial load
duke
parents:
diff changeset
519 // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // other threads. The "ReduceSignalUsage" boolean tells us not to alter
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // the dispositions or masks wrt these signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
522 // Programs embedding the VM that want to use the above signals for their
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // own purposes must, at this time, use the "-Xrs" option to prevent
a61af66fc99e Initial load
duke
parents:
diff changeset
524 // interference with shutdown hooks and BREAK_SIGNAL thread dumping.
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // (See bug 4345157, and other related bugs).
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // In reality, though, unblocking these signals is really a nop, since
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // these signals are not blocked by default.
a61af66fc99e Initial load
duke
parents:
diff changeset
528 sigemptyset(&unblocked_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
529 sigemptyset(&allowdebug_blocked_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
530 sigaddset(&unblocked_sigs, SIGILL);
a61af66fc99e Initial load
duke
parents:
diff changeset
531 sigaddset(&unblocked_sigs, SIGSEGV);
a61af66fc99e Initial load
duke
parents:
diff changeset
532 sigaddset(&unblocked_sigs, SIGBUS);
a61af66fc99e Initial load
duke
parents:
diff changeset
533 sigaddset(&unblocked_sigs, SIGFPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
534 sigaddset(&unblocked_sigs, SR_signum);
a61af66fc99e Initial load
duke
parents:
diff changeset
535
a61af66fc99e Initial load
duke
parents:
diff changeset
536 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
537 if (!os::Linux::is_sig_ignored(SHUTDOWN1_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
538 sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
539 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541 if (!os::Linux::is_sig_ignored(SHUTDOWN2_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
542 sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
545 if (!os::Linux::is_sig_ignored(SHUTDOWN3_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
546 sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
547 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // Fill in signals that are blocked by all but the VM thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
551 sigemptyset(&vm_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
552 if (!ReduceSignalUsage)
a61af66fc99e Initial load
duke
parents:
diff changeset
553 sigaddset(&vm_sigs, BREAK_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
554 debug_only(signal_sets_initialized = true);
a61af66fc99e Initial load
duke
parents:
diff changeset
555
a61af66fc99e Initial load
duke
parents:
diff changeset
556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // These are signals that are unblocked while a thread is running Java.
a61af66fc99e Initial load
duke
parents:
diff changeset
559 // (For some reason, they get blocked by default.)
a61af66fc99e Initial load
duke
parents:
diff changeset
560 sigset_t* os::Linux::unblocked_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
561 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
562 return &unblocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
564
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // These are the signals that are blocked while a (non-VM) thread is
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // running Java. Only the VM thread handles these signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
567 sigset_t* os::Linux::vm_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
569 return &vm_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
571
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // These are signals that are blocked during cond_wait to allow debugger in
a61af66fc99e Initial load
duke
parents:
diff changeset
573 sigset_t* os::Linux::allowdebug_blocked_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
574 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
575 return &allowdebug_blocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
576 }
a61af66fc99e Initial load
duke
parents:
diff changeset
577
a61af66fc99e Initial load
duke
parents:
diff changeset
578 void os::Linux::hotspot_sigmask(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
579
a61af66fc99e Initial load
duke
parents:
diff changeset
580 //Save caller's signal mask before setting VM signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
581 sigset_t caller_sigmask;
a61af66fc99e Initial load
duke
parents:
diff changeset
582 pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask);
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
585 osthread->set_caller_sigmask(caller_sigmask);
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 pthread_sigmask(SIG_UNBLOCK, os::Linux::unblocked_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
590 if (thread->is_VM_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // Only the VM thread handles BREAK_SIGNAL ...
a61af66fc99e Initial load
duke
parents:
diff changeset
592 pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
593 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // ... all other threads block BREAK_SIGNAL
a61af66fc99e Initial load
duke
parents:
diff changeset
595 pthread_sigmask(SIG_BLOCK, vm_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 }
a61af66fc99e Initial load
duke
parents:
diff changeset
597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
598 }
a61af66fc99e Initial load
duke
parents:
diff changeset
599
a61af66fc99e Initial load
duke
parents:
diff changeset
600 //////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // detecting pthread library
a61af66fc99e Initial load
duke
parents:
diff changeset
602
a61af66fc99e Initial load
duke
parents:
diff changeset
603 void os::Linux::libpthread_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // Save glibc and pthread version strings. Note that _CS_GNU_LIBC_VERSION
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // and _CS_GNU_LIBPTHREAD_VERSION are supported in glibc >= 2.3.2. Use a
a61af66fc99e Initial load
duke
parents:
diff changeset
606 // generic name for earlier versions.
a61af66fc99e Initial load
duke
parents:
diff changeset
607 // Define macros here so we can build HotSpot on old systems.
a61af66fc99e Initial load
duke
parents:
diff changeset
608 # ifndef _CS_GNU_LIBC_VERSION
a61af66fc99e Initial load
duke
parents:
diff changeset
609 # define _CS_GNU_LIBC_VERSION 2
a61af66fc99e Initial load
duke
parents:
diff changeset
610 # endif
a61af66fc99e Initial load
duke
parents:
diff changeset
611 # ifndef _CS_GNU_LIBPTHREAD_VERSION
a61af66fc99e Initial load
duke
parents:
diff changeset
612 # define _CS_GNU_LIBPTHREAD_VERSION 3
a61af66fc99e Initial load
duke
parents:
diff changeset
613 # endif
a61af66fc99e Initial load
duke
parents:
diff changeset
614
a61af66fc99e Initial load
duke
parents:
diff changeset
615 size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
616 if (n > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
617 char *str = (char *)malloc(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 confstr(_CS_GNU_LIBC_VERSION, str, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
619 os::Linux::set_glibc_version(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
620 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
621 // _CS_GNU_LIBC_VERSION is not supported, try gnu_get_libc_version()
a61af66fc99e Initial load
duke
parents:
diff changeset
622 static char _gnu_libc_version[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
623 jio_snprintf(_gnu_libc_version, sizeof(_gnu_libc_version),
a61af66fc99e Initial load
duke
parents:
diff changeset
624 "glibc %s %s", gnu_get_libc_version(), gnu_get_libc_release());
a61af66fc99e Initial load
duke
parents:
diff changeset
625 os::Linux::set_glibc_version(_gnu_libc_version);
a61af66fc99e Initial load
duke
parents:
diff changeset
626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
627
a61af66fc99e Initial load
duke
parents:
diff changeset
628 n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
629 if (n > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
630 char *str = (char *)malloc(n);
a61af66fc99e Initial load
duke
parents:
diff changeset
631 confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
a61af66fc99e Initial load
duke
parents:
diff changeset
633 // us "NPTL-0.29" even we are running with LinuxThreads. Check if this
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
634 // is the case. LinuxThreads has a hard limit on max number of threads.
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
635 // So sysconf(_SC_THREAD_THREADS_MAX) will return a positive value.
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
636 // On the other hand, NPTL does not have such a limit, sysconf()
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
637 // will return -1 and errno is not changed. Check if it is really NPTL.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
638 if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 &&
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
639 strstr(str, "NPTL") &&
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
640 sysconf(_SC_THREAD_THREADS_MAX) > 0) {
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
641 free(str);
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
642 os::Linux::set_libpthread_version("linuxthreads");
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
643 } else {
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
644 os::Linux::set_libpthread_version(str);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
646 } else {
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
647 // glibc before 2.3.2 only has LinuxThreads.
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
648 os::Linux::set_libpthread_version("linuxthreads");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 if (strstr(libpthread_version(), "NPTL")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
652 os::Linux::set_is_NPTL();
a61af66fc99e Initial load
duke
parents:
diff changeset
653 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
654 os::Linux::set_is_LinuxThreads();
a61af66fc99e Initial load
duke
parents:
diff changeset
655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
656
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // LinuxThreads have two flavors: floating-stack mode, which allows variable
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // stack size; and fixed-stack mode. NPTL is always floating-stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
659 if (os::Linux::is_NPTL() || os::Linux::supports_variable_stack_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
660 os::Linux::set_is_floating_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
663
a61af66fc99e Initial load
duke
parents:
diff changeset
664 /////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // thread stack
a61af66fc99e Initial load
duke
parents:
diff changeset
666
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // Force Linux kernel to expand current thread stack. If "bottom" is close
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // to the stack guard, caller should block all signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
669 //
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // MAP_GROWSDOWN:
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // A special mmap() flag that is used to implement thread stacks. It tells
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // kernel that the memory region should extend downwards when needed. This
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // allows early versions of LinuxThreads to only mmap the first few pages
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // when creating a new thread. Linux kernel will automatically expand thread
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // stack as needed (on page faults).
a61af66fc99e Initial load
duke
parents:
diff changeset
676 //
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // However, because the memory region of a MAP_GROWSDOWN stack can grow on
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // demand, if a page fault happens outside an already mapped MAP_GROWSDOWN
a61af66fc99e Initial load
duke
parents:
diff changeset
679 // region, it's hard to tell if the fault is due to a legitimate stack
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // access or because of reading/writing non-exist memory (e.g. buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // overrun). As a rule, if the fault happens below current stack pointer,
a61af66fc99e Initial load
duke
parents:
diff changeset
682 // Linux kernel does not expand stack, instead a SIGSEGV is sent to the
a61af66fc99e Initial load
duke
parents:
diff changeset
683 // application (see Linux kernel fault.c).
a61af66fc99e Initial load
duke
parents:
diff changeset
684 //
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // This Linux feature can cause SIGSEGV when VM bangs thread stack for
a61af66fc99e Initial load
duke
parents:
diff changeset
686 // stack overflow detection.
a61af66fc99e Initial load
duke
parents:
diff changeset
687 //
a61af66fc99e Initial load
duke
parents:
diff changeset
688 // Newer version of LinuxThreads (since glibc-2.2, or, RH-7.x) and NPTL do
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // not use this flag. However, the stack of initial thread is not created
a61af66fc99e Initial load
duke
parents:
diff changeset
690 // by pthread, it is still MAP_GROWSDOWN. Also it's possible (though
a61af66fc99e Initial load
duke
parents:
diff changeset
691 // unlikely) that user code can create a thread with MAP_GROWSDOWN stack
a61af66fc99e Initial load
duke
parents:
diff changeset
692 // and then attach the thread to JVM.
a61af66fc99e Initial load
duke
parents:
diff changeset
693 //
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // To get around the problem and allow stack banging on Linux, we need to
a61af66fc99e Initial load
duke
parents:
diff changeset
695 // manually expand thread stack after receiving the SIGSEGV.
a61af66fc99e Initial load
duke
parents:
diff changeset
696 //
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // There are two ways to expand thread stack to address "bottom", we used
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // both of them in JVM before 1.5:
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // 1. adjust stack pointer first so that it is below "bottom", and then
a61af66fc99e Initial load
duke
parents:
diff changeset
700 // touch "bottom"
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // 2. mmap() the page in question
a61af66fc99e Initial load
duke
parents:
diff changeset
702 //
a61af66fc99e Initial load
duke
parents:
diff changeset
703 // Now alternate signal stack is gone, it's harder to use 2. For instance,
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // if current sp is already near the lower end of page 101, and we need to
a61af66fc99e Initial load
duke
parents:
diff changeset
705 // call mmap() to map page 100, it is possible that part of the mmap() frame
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // will be placed in page 100. When page 100 is mapped, it is zero-filled.
a61af66fc99e Initial load
duke
parents:
diff changeset
707 // That will destroy the mmap() frame and cause VM to crash.
a61af66fc99e Initial load
duke
parents:
diff changeset
708 //
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // The following code works by adjusting sp first, then accessing the "bottom"
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // page to force a page fault. Linux kernel will then automatically expand the
a61af66fc99e Initial load
duke
parents:
diff changeset
711 // stack mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
712 //
a61af66fc99e Initial load
duke
parents:
diff changeset
713 // _expand_stack_to() assumes its frame size is less than page size, which
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // should always be true if the function is not inlined.
a61af66fc99e Initial load
duke
parents:
diff changeset
715
a61af66fc99e Initial load
duke
parents:
diff changeset
716 #if __GNUC__ < 3 // gcc 2.x does not support noinline attribute
a61af66fc99e Initial load
duke
parents:
diff changeset
717 #define NOINLINE
a61af66fc99e Initial load
duke
parents:
diff changeset
718 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
719 #define NOINLINE __attribute__ ((noinline))
a61af66fc99e Initial load
duke
parents:
diff changeset
720 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
721
a61af66fc99e Initial load
duke
parents:
diff changeset
722 static void _expand_stack_to(address bottom) NOINLINE;
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 static void _expand_stack_to(address bottom) {
a61af66fc99e Initial load
duke
parents:
diff changeset
725 address sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
726 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
727 volatile char *p;
a61af66fc99e Initial load
duke
parents:
diff changeset
728
a61af66fc99e Initial load
duke
parents:
diff changeset
729 // Adjust bottom to point to the largest address within the same page, it
a61af66fc99e Initial load
duke
parents:
diff changeset
730 // gives us a one-page buffer if alloca() allocates slightly more memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
731 bottom = (address)align_size_down((uintptr_t)bottom, os::Linux::page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
732 bottom += os::Linux::page_size() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
733
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // sp might be slightly above current stack pointer; if that's the case, we
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // will alloca() a little more space than necessary, which is OK. Don't use
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // os::current_stack_pointer(), as its result can be slightly below current
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // stack pointer, causing us to not alloca enough to reach "bottom".
a61af66fc99e Initial load
duke
parents:
diff changeset
738 sp = (address)&sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
739
a61af66fc99e Initial load
duke
parents:
diff changeset
740 if (sp > bottom) {
a61af66fc99e Initial load
duke
parents:
diff changeset
741 size = sp - bottom;
a61af66fc99e Initial load
duke
parents:
diff changeset
742 p = (volatile char *)alloca(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
743 assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?");
a61af66fc99e Initial load
duke
parents:
diff changeset
744 p[0] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
749 assert(t!=NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
750 assert(t->osthread()->expanding_stack(), "expand should be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
751 assert(t->stack_base() != NULL, "stack_base was not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
752
a61af66fc99e Initial load
duke
parents:
diff changeset
753 if (addr < t->stack_base() && addr >= t->stack_yellow_zone_base()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
754 sigset_t mask_all, old_sigset;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 sigfillset(&mask_all);
a61af66fc99e Initial load
duke
parents:
diff changeset
756 pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset);
a61af66fc99e Initial load
duke
parents:
diff changeset
757 _expand_stack_to(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
758 pthread_sigmask(SIG_SETMASK, &old_sigset, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
759 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
761 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
763
a61af66fc99e Initial load
duke
parents:
diff changeset
764 //////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // create new thread
a61af66fc99e Initial load
duke
parents:
diff changeset
766
a61af66fc99e Initial load
duke
parents:
diff changeset
767 static address highest_vm_reserved_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
768
a61af66fc99e Initial load
duke
parents:
diff changeset
769 // check if it's safe to start a new thread
a61af66fc99e Initial load
duke
parents:
diff changeset
770 static bool _thread_safety_check(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
771 if (os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // Fixed stack LinuxThreads (SuSE Linux/x86, and some versions of Redhat)
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // Heap is mmap'ed at lower end of memory space. Thread stacks are
a61af66fc99e Initial load
duke
parents:
diff changeset
774 // allocated (MAP_FIXED) from high address space. Every thread stack
a61af66fc99e Initial load
duke
parents:
diff changeset
775 // occupies a fixed size slot (usually 2Mbytes, but user can change
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // it to other values if they rebuild LinuxThreads).
a61af66fc99e Initial load
duke
parents:
diff changeset
777 //
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // Problem with MAP_FIXED is that mmap() can still succeed even part of
a61af66fc99e Initial load
duke
parents:
diff changeset
779 // the memory region has already been mmap'ed. That means if we have too
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // many threads and/or very large heap, eventually thread stack will
a61af66fc99e Initial load
duke
parents:
diff changeset
781 // collide with heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
782 //
a61af66fc99e Initial load
duke
parents:
diff changeset
783 // Here we try to prevent heap/stack collision by comparing current
a61af66fc99e Initial load
duke
parents:
diff changeset
784 // stack bottom with the highest address that has been mmap'ed by JVM
a61af66fc99e Initial load
duke
parents:
diff changeset
785 // plus a safety margin for memory maps created by native code.
a61af66fc99e Initial load
duke
parents:
diff changeset
786 //
a61af66fc99e Initial load
duke
parents:
diff changeset
787 // This feature can be disabled by setting ThreadSafetyMargin to 0
a61af66fc99e Initial load
duke
parents:
diff changeset
788 //
a61af66fc99e Initial load
duke
parents:
diff changeset
789 if (ThreadSafetyMargin > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
790 address stack_bottom = os::current_stack_base() - os::current_stack_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
791
a61af66fc99e Initial load
duke
parents:
diff changeset
792 // not safe if our stack extends below the safety margin
a61af66fc99e Initial load
duke
parents:
diff changeset
793 return stack_bottom - ThreadSafetyMargin >= highest_vm_reserved_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
794 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
795 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
797 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
798 // Floating stack LinuxThreads or NPTL:
a61af66fc99e Initial load
duke
parents:
diff changeset
799 // Unlike fixed stack LinuxThreads, thread stacks are not MAP_FIXED. When
a61af66fc99e Initial load
duke
parents:
diff changeset
800 // there's not enough space left, pthread_create() will fail. If we come
a61af66fc99e Initial load
duke
parents:
diff changeset
801 // here, that means enough space has been reserved for stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
802 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806 // Thread start routine for all newly created threads
a61af66fc99e Initial load
duke
parents:
diff changeset
807 static void *java_start(Thread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // Try to randomize the cache line index of hot stack frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // This helps when threads of the same stack traces evict each other's
a61af66fc99e Initial load
duke
parents:
diff changeset
810 // cache lines. The threads can be either from the same JVM instance, or
a61af66fc99e Initial load
duke
parents:
diff changeset
811 // from different JVM instances. The benefit is especially true for
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // processors with hyperthreading technology.
a61af66fc99e Initial load
duke
parents:
diff changeset
813 static int counter = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
814 int pid = os::current_process_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
815 alloca(((pid ^ counter++) & 7) * 128);
a61af66fc99e Initial load
duke
parents:
diff changeset
816
a61af66fc99e Initial load
duke
parents:
diff changeset
817 ThreadLocalStorage::set_thread(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
820 Monitor* sync = osthread->startThread_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
821
a61af66fc99e Initial load
duke
parents:
diff changeset
822 // non floating stack LinuxThreads needs extra check, see above
a61af66fc99e Initial load
duke
parents:
diff changeset
823 if (!_thread_safety_check(thread)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // notify parent thread
a61af66fc99e Initial load
duke
parents:
diff changeset
825 MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
826 osthread->set_state(ZOMBIE);
a61af66fc99e Initial load
duke
parents:
diff changeset
827 sync->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
828 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 // thread_id is kernel thread id (similar to Solaris LWP id)
a61af66fc99e Initial load
duke
parents:
diff changeset
832 osthread->set_thread_id(os::Linux::gettid());
a61af66fc99e Initial load
duke
parents:
diff changeset
833
a61af66fc99e Initial load
duke
parents:
diff changeset
834 if (UseNUMA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
835 int lgrp_id = os::numa_get_group_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
836 if (lgrp_id != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
837 thread->set_lgrp_id(lgrp_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
840 // initialize signal mask for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
841 os::Linux::hotspot_sigmask(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
842
a61af66fc99e Initial load
duke
parents:
diff changeset
843 // initialize floating point control register
a61af66fc99e Initial load
duke
parents:
diff changeset
844 os::Linux::init_thread_fpu_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
845
a61af66fc99e Initial load
duke
parents:
diff changeset
846 // handshaking with parent thread
a61af66fc99e Initial load
duke
parents:
diff changeset
847 {
a61af66fc99e Initial load
duke
parents:
diff changeset
848 MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // notify parent thread
a61af66fc99e Initial load
duke
parents:
diff changeset
851 osthread->set_state(INITIALIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
852 sync->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
853
a61af66fc99e Initial load
duke
parents:
diff changeset
854 // wait until os::start_thread()
a61af66fc99e Initial load
duke
parents:
diff changeset
855 while (osthread->get_state() == INITIALIZED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
856 sync->wait(Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
857 }
a61af66fc99e Initial load
duke
parents:
diff changeset
858 }
a61af66fc99e Initial load
duke
parents:
diff changeset
859
a61af66fc99e Initial load
duke
parents:
diff changeset
860 // call one more level start routine
a61af66fc99e Initial load
duke
parents:
diff changeset
861 thread->run();
a61af66fc99e Initial load
duke
parents:
diff changeset
862
a61af66fc99e Initial load
duke
parents:
diff changeset
863 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
865
a61af66fc99e Initial load
duke
parents:
diff changeset
866 bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
867 assert(thread->osthread() == NULL, "caller responsible");
a61af66fc99e Initial load
duke
parents:
diff changeset
868
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // Allocate the OSThread object
a61af66fc99e Initial load
duke
parents:
diff changeset
870 OSThread* osthread = new OSThread(NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
871 if (osthread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
872 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
874
a61af66fc99e Initial load
duke
parents:
diff changeset
875 // set the correct thread state
a61af66fc99e Initial load
duke
parents:
diff changeset
876 osthread->set_thread_type(thr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
877
a61af66fc99e Initial load
duke
parents:
diff changeset
878 // Initial state is ALLOCATED but not INITIALIZED
a61af66fc99e Initial load
duke
parents:
diff changeset
879 osthread->set_state(ALLOCATED);
a61af66fc99e Initial load
duke
parents:
diff changeset
880
a61af66fc99e Initial load
duke
parents:
diff changeset
881 thread->set_osthread(osthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
882
a61af66fc99e Initial load
duke
parents:
diff changeset
883 // init thread attributes
a61af66fc99e Initial load
duke
parents:
diff changeset
884 pthread_attr_t attr;
a61af66fc99e Initial load
duke
parents:
diff changeset
885 pthread_attr_init(&attr);
a61af66fc99e Initial load
duke
parents:
diff changeset
886 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
a61af66fc99e Initial load
duke
parents:
diff changeset
887
a61af66fc99e Initial load
duke
parents:
diff changeset
888 // stack size
a61af66fc99e Initial load
duke
parents:
diff changeset
889 if (os::Linux::supports_variable_stack_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // calculate stack size if it's not specified by caller
a61af66fc99e Initial load
duke
parents:
diff changeset
891 if (stack_size == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
892 stack_size = os::Linux::default_stack_size(thr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
893
a61af66fc99e Initial load
duke
parents:
diff changeset
894 switch (thr_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 case os::java_thread:
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
896 // Java threads use ThreadStackSize which default value can be
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
897 // changed with the flag -Xss
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
898 assert (JavaThread::stack_size_at_create() > 0, "this should be set");
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
899 stack_size = JavaThread::stack_size_at_create();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
900 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
901 case os::compiler_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
902 if (CompilerThreadStackSize > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
903 stack_size = (size_t)(CompilerThreadStackSize * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
904 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
905 } // else fall through:
a61af66fc99e Initial load
duke
parents:
diff changeset
906 // use VMThreadStackSize if CompilerThreadStackSize is not defined
a61af66fc99e Initial load
duke
parents:
diff changeset
907 case os::vm_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
908 case os::pgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
909 case os::cgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
910 case os::watcher_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
911 if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
912 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
913 }
a61af66fc99e Initial load
duke
parents:
diff changeset
914 }
a61af66fc99e Initial load
duke
parents:
diff changeset
915
a61af66fc99e Initial load
duke
parents:
diff changeset
916 stack_size = MAX2(stack_size, os::Linux::min_stack_allowed);
a61af66fc99e Initial load
duke
parents:
diff changeset
917 pthread_attr_setstacksize(&attr, stack_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
918 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 // let pthread_create() pick the default value.
a61af66fc99e Initial load
duke
parents:
diff changeset
920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // glibc guard page
a61af66fc99e Initial load
duke
parents:
diff changeset
923 pthread_attr_setguardsize(&attr, os::Linux::default_guard_size(thr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 ThreadState state;
a61af66fc99e Initial load
duke
parents:
diff changeset
926
a61af66fc99e Initial load
duke
parents:
diff changeset
927 {
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // Serialize thread creation if we are running with fixed stack LinuxThreads
a61af66fc99e Initial load
duke
parents:
diff changeset
929 bool lock = os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
930 if (lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
931 os::Linux::createThread_lock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 pthread_t tid;
a61af66fc99e Initial load
duke
parents:
diff changeset
935 int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
936
a61af66fc99e Initial load
duke
parents:
diff changeset
937 pthread_attr_destroy(&attr);
a61af66fc99e Initial load
duke
parents:
diff changeset
938
a61af66fc99e Initial load
duke
parents:
diff changeset
939 if (ret != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 if (PrintMiscellaneous && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
941 perror("pthread_create()");
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943 // Need to clean up stuff we've allocated so far
a61af66fc99e Initial load
duke
parents:
diff changeset
944 thread->set_osthread(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
945 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
946 if (lock) os::Linux::createThread_lock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
947 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // Store pthread info into the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
951 osthread->set_pthread_id(tid);
a61af66fc99e Initial load
duke
parents:
diff changeset
952
a61af66fc99e Initial load
duke
parents:
diff changeset
953 // Wait until child thread is either initialized or aborted
a61af66fc99e Initial load
duke
parents:
diff changeset
954 {
a61af66fc99e Initial load
duke
parents:
diff changeset
955 Monitor* sync_with_child = osthread->startThread_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
956 MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
957 while ((state = osthread->get_state()) == ALLOCATED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
958 sync_with_child->wait(Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
961
a61af66fc99e Initial load
duke
parents:
diff changeset
962 if (lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
963 os::Linux::createThread_lock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
965 }
a61af66fc99e Initial load
duke
parents:
diff changeset
966
a61af66fc99e Initial load
duke
parents:
diff changeset
967 // Aborted due to thread limit being reached
a61af66fc99e Initial load
duke
parents:
diff changeset
968 if (state == ZOMBIE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
969 thread->set_osthread(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
970 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
971 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
973
a61af66fc99e Initial load
duke
parents:
diff changeset
974 // The thread is returned suspended (in state INITIALIZED),
a61af66fc99e Initial load
duke
parents:
diff changeset
975 // and is started higher up in the call chain
a61af66fc99e Initial load
duke
parents:
diff changeset
976 assert(state == INITIALIZED, "race condition");
a61af66fc99e Initial load
duke
parents:
diff changeset
977 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
979
a61af66fc99e Initial load
duke
parents:
diff changeset
980 /////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // attach existing thread
a61af66fc99e Initial load
duke
parents:
diff changeset
982
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // bootstrap the main thread
a61af66fc99e Initial load
duke
parents:
diff changeset
984 bool os::create_main_thread(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
985 assert(os::Linux::_main_thread == pthread_self(), "should be called inside main thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
986 return create_attached_thread(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
988
a61af66fc99e Initial load
duke
parents:
diff changeset
989 bool os::create_attached_thread(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
990 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
991 thread->verify_not_published();
a61af66fc99e Initial load
duke
parents:
diff changeset
992 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
993
a61af66fc99e Initial load
duke
parents:
diff changeset
994 // Allocate the OSThread object
a61af66fc99e Initial load
duke
parents:
diff changeset
995 OSThread* osthread = new OSThread(NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
996
a61af66fc99e Initial load
duke
parents:
diff changeset
997 if (osthread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
998 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1000
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 // Store pthread info into the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 osthread->set_thread_id(os::Linux::gettid());
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 osthread->set_pthread_id(::pthread_self());
a61af66fc99e Initial load
duke
parents:
diff changeset
1004
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 // initialize floating point control register
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 os::Linux::init_thread_fpu_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
1007
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 // Initial thread state is RUNNABLE
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 osthread->set_state(RUNNABLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1010
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 thread->set_osthread(osthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1012
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 if (UseNUMA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 int lgrp_id = os::numa_get_group_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 if (lgrp_id != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 thread->set_lgrp_id(lgrp_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 if (os::Linux::is_initial_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // If current thread is initial thread, its stack is mapped on demand,
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // see notes about MAP_GROWSDOWN. Here we try to force kernel to map
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // the entire stack region to avoid SEGV in stack banging.
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // It is also useful to get around the heap-stack-gap problem on SuSE
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 // kernel (see 4821821 for details). We first expand stack to the top
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 // of yellow zone, then enable stack yellow zone (order is significant,
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 // enabling yellow zone first will crash JVM on SuSE Linux), so there
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 // is no gap between the last two virtual memory regions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1029
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 JavaThread *jt = (JavaThread *)thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 address addr = jt->stack_yellow_zone_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 assert(addr != NULL, "initialization problem?");
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 assert(jt->stack_available(addr) > 0, "stack guard should not be enabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 osthread->set_expanding_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 os::Linux::manually_expand_stack(jt, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 osthread->clear_expanding_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1039
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 // initialize signal mask for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 // and save the caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 os::Linux::hotspot_sigmask(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1043
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1046
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 void os::pd_start_thread(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 OSThread * osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 assert(osthread->get_state() != INITIALIZED, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 Monitor* sync_with_child = osthread->startThread_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 sync_with_child->notify();
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1054
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 // Free Linux resources related to the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 void os::free_thread(OSThread* osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 assert(osthread != NULL, "osthread not set");
a61af66fc99e Initial load
duke
parents:
diff changeset
1058
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 if (Thread::current()->osthread() == osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 // Restore caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 sigset_t sigmask = osthread->caller_sigmask();
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 pthread_sigmask(SIG_SETMASK, &sigmask, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1064
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 //////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // thread local storage
a61af66fc99e Initial load
duke
parents:
diff changeset
1070
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 int os::allocate_thread_local_storage() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 pthread_key_t key;
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 int rslt = pthread_key_create(&key, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 assert(rslt == 0, "cannot allocate thread local storage");
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 return (int)key;
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // Note: This is currently not used by VM, as we don't destroy TLS key
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // on VM exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 void os::free_thread_local_storage(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 int rslt = pthread_key_delete((pthread_key_t)index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 assert(rslt == 0, "invalid index");
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1084
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 void os::thread_local_storage_at_put(int index, void* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 int rslt = pthread_setspecific((pthread_key_t)index, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 assert(rslt == 0, "pthread_setspecific failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1089
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 extern "C" Thread* get_thread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 return ThreadLocalStorage::thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1093
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 //////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 // initial thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1096
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 // Check if current thread is the initial thread, similar to Solaris thr_main.
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 bool os::Linux::is_initial_thread(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 char dummy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 // If called before init complete, thread stack bottom will be null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 // Can be called if fatal error occurs before initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 if (initial_thread_stack_bottom() == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 assert(initial_thread_stack_bottom() != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 initial_thread_stack_size() != 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 "os::init did not locate initial thread's stack region");
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 if ((address)&dummy >= initial_thread_stack_bottom() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 (address)&dummy < initial_thread_stack_bottom() + initial_thread_stack_size())
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 else return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 // Find the virtual memory area that contains addr
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 static bool find_vma(address addr, address* vma_low, address* vma_high) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 FILE *fp = fopen("/proc/self/maps", "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 if (fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 address low, high;
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 while (!feof(fp)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 if (fscanf(fp, "%p-%p", &low, &high) == 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 if (low <= addr && addr < high) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 if (vma_low) *vma_low = low;
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 if (vma_high) *vma_high = high;
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 fclose (fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 int ch = fgetc(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 if (ch == EOF || ch == (int)'\n') break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1135
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // Locate initial thread stack. This special handling of initial thread stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // is needed because pthread_getattr_np() on most (all?) Linux distros returns
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // bogus value for initial thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 void os::Linux::capture_initial_stack(size_t max_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // stack size is the easy part, get it from RLIMIT_STACK
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 size_t stack_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 struct rlimit rlim;
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 getrlimit(RLIMIT_STACK, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 stack_size = rlim.rlim_cur;
a61af66fc99e Initial load
duke
parents:
diff changeset
1145
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // 6308388: a bug in ld.so will relocate its own .data section to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // lower end of primordial stack; reduce ulimit -s value a little bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // so we won't install guard page on ld.so's data section.
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 stack_size -= 2 * page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1150
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // 7.1, in both cases we will get 2G in return value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // SuSE 7.2, Debian) can not handle alternate signal stack correctly
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 // for initial thread if its stack size exceeds 6M. Cap it at 2M,
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 // in case other parts in glibc still assumes 2M max stack size.
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 // FIXME: alt signal stack is gone, maybe we can relax this constraint?
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 #ifndef IA64
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 if (stack_size > 2 * K * K) stack_size = 2 * K * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 if (stack_size > 4 * K * K) stack_size = 4 * K * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1164
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // Try to figure out where the stack base (top) is. This is harder.
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 // When an application is started, glibc saves the initial stack pointer in
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 // a global variable "__libc_stack_end", which is then used by system
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 // libraries. __libc_stack_end should be pretty close to stack top. The
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 // variable is available since the very early days. However, because it is
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 // a private interface, it could disappear in the future.
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // Linux kernel saves start_stack information in /proc/<pid>/stat. Similar
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // to __libc_stack_end, it is very close to stack top, but isn't the real
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // stack top. Note that /proc may not exist if VM is running as a chroot
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 // program, so reading /proc/<pid>/stat could fail. Also the contents of
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // /proc/<pid>/stat could change in the future (though unlikely).
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // We try __libc_stack_end first. If that doesn't work, look for
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // /proc/<pid>/stat. If neither of them works, we use current stack pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 // as a hint, which should work well in most cases.
a61af66fc99e Initial load
duke
parents:
diff changeset
1182
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 uintptr_t stack_start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1184
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 // try __libc_stack_end first
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 uintptr_t *p = (uintptr_t *)dlsym(RTLD_DEFAULT, "__libc_stack_end");
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 if (p && *p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 stack_start = *p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 // see if we can get the start_stack field from /proc/self/stat
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 FILE *fp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 int pid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 char state;
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 int ppid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 int pgrp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 int session;
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 int nr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 int tpgrp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 unsigned long flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 unsigned long minflt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 unsigned long cminflt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 unsigned long majflt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 unsigned long cmajflt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 unsigned long utime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 unsigned long stime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 long cutime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 long cstime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 long prio;
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 long nice;
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 long junk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 long it_real;
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 uintptr_t start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 uintptr_t vsize;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1214 intptr_t rss;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1215 uintptr_t rsslim;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 uintptr_t scodes;
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 uintptr_t ecode;
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1219
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 // Figure what the primordial thread stack base is. Code is inspired
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 // by email from Hans Boehm. /proc/self/stat begins with current pid,
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 // followed by command name surrounded by parentheses, state, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 char stat[2048];
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 int statlen;
a61af66fc99e Initial load
duke
parents:
diff changeset
1225
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 fp = fopen("/proc/self/stat", "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 if (fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 statlen = fread(stat, 1, 2047, fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 stat[statlen] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1231
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // Skip pid and the command string. Note that we could be dealing with
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 // weird command names, e.g. user could decide to rename java launcher
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 // to "java 1.4.2 :)", then the stat file would look like
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 // 1234 (java 1.4.2 :)) R ... ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 // We don't really need to know the command string, just find the last
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // occurrence of ")" and then start parsing from there. See bug 4726580.
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 char * s = strrchr(stat, ')');
a61af66fc99e Initial load
duke
parents:
diff changeset
1239
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 if (s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 // Skip blank chars
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 do s++; while (isspace(*s));
a61af66fc99e Initial load
duke
parents:
diff changeset
1244
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1245 #define _UFM UINTX_FORMAT
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1246 #define _DFM INTX_FORMAT
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1247
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1248 /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1249 /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1250 i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 &state, /* 3 %c */
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 &ppid, /* 4 %d */
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 &pgrp, /* 5 %d */
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 &session, /* 6 %d */
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 &nr, /* 7 %d */
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 &tpgrp, /* 8 %d */
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 &flags, /* 9 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 &minflt, /* 10 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 &cminflt, /* 11 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 &majflt, /* 12 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 &cmajflt, /* 13 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 &utime, /* 14 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 &stime, /* 15 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 &cutime, /* 16 %ld */
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 &cstime, /* 17 %ld */
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 &prio, /* 18 %ld */
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 &nice, /* 19 %ld */
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 &junk, /* 20 %ld */
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 &it_real, /* 21 %ld */
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1270 &start, /* 22 UINTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1271 &vsize, /* 23 UINTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1272 &rss, /* 24 INTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1273 &rsslim, /* 25 UINTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1274 &scodes, /* 26 UINTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1275 &ecode, /* 27 UINTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1276 &stack_start); /* 28 UINTX_FORMAT */
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1278
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1279 #undef _UFM
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1280 #undef _DFM
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1281
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 if (i != 28 - 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 assert(false, "Bad conversion from /proc/self/stat");
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // product mode - assume we are the initial thread, good luck in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // embedded case.
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 warning("Can't detect initial thread stack location - bad conversion");
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 stack_start = (uintptr_t) &rlim;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 // For some reason we can't open /proc/self/stat (for example, running on
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 // FreeBSD with a Linux emulator, or inside chroot), this should work for
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 // most cases, so don't abort:
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 warning("Can't detect initial thread stack location - no /proc/self/stat");
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 stack_start = (uintptr_t) &rlim;
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1297
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 // Now we have a pointer (stack_start) very close to the stack top, the
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // next thing to do is to figure out the exact location of stack top. We
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 // can find out the virtual memory area that contains stack_start by
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 // reading /proc/self/maps, it should be the last vma in /proc/self/maps,
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 // and its upper limit is the real stack top. (again, this would fail if
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // running inside chroot, because /proc may not exist.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1304
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 uintptr_t stack_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 address low, high;
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 if (find_vma((address)stack_start, &low, &high)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // success, "high" is the true stack top. (ignore "low", because initial
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 // thread stack grows on demand, its real bottom is high - RLIMIT_STACK.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 stack_top = (uintptr_t)high;
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // failed, likely because /proc/self/maps does not exist
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 warning("Can't detect initial thread stack location - find_vma failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // best effort: stack_start is normally within a few pages below the real
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 // stack top, use it as stack top, and reduce stack size so we won't put
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // guard page outside stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 stack_top = stack_start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 stack_size -= 16 * page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1320
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // stack_top could be partially down the page so align it
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 stack_top = align_size_up(stack_top, page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1323
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 if (max_size && stack_size > max_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 _initial_thread_stack_size = max_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 _initial_thread_stack_size = stack_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1329
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1333
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 // time support
a61af66fc99e Initial load
duke
parents:
diff changeset
1336
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 // Time since start-up in seconds to a fine granularity.
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 // Used by VMSelfDestructTimer and the MemProfiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 double os::elapsedTime() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1340
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 return (double)(os::elapsed_counter()) * 0.000001;
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1343
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 jlong os::elapsed_counter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 timeval time;
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 int status = gettimeofday(&time, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1349
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 jlong os::elapsed_frequency() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 return (1000 * 1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1353
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1354 // For now, we say that linux does not support vtime. I have no idea
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1355 // whether it can actually be made to (DLD, 9/13/05).
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1356
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1357 bool os::supports_vtime() { return false; }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1358 bool os::enable_vtime() { return false; }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1359 bool os::vtime_enabled() { return false; }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1360 double os::elapsedVTime() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1361 // better than nothing, but not much
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1362 return elapsedTime();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1363 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1364
61
5a76ab815e34 6667833: Remove CacheTimeMillis
sbohne
parents: 0
diff changeset
1365 jlong os::javaTimeMillis() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 timeval time;
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 int status = gettimeofday(&time, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 assert(status != -1, "linux error");
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1371
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 #ifndef CLOCK_MONOTONIC
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 #define CLOCK_MONOTONIC (1)
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1375
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 void os::Linux::clock_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // we do dlopen's in this particular order due to bug in linux
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 // dynamical loader (see 6348968) leading to crash on exit
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 void* handle = dlopen("librt.so.1", RTLD_LAZY);
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 if (handle == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 handle = dlopen("librt.so", RTLD_LAZY);
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1383
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 if (handle) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 int (*clock_getres_func)(clockid_t, struct timespec*) =
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres");
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 int (*clock_gettime_func)(clockid_t, struct timespec*) =
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_gettime");
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 if (clock_getres_func && clock_gettime_func) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 // See if monotonic clock is supported by the kernel. Note that some
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 // early implementations simply return kernel jiffies (updated every
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 // 1/100 or 1/1000 second). It would be bad to use such a low res clock
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 // for nano time (though the monotonic property is still nice to have).
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 // It's fixed in newer kernels, however clock_getres() still returns
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // 1/HZ. We check if clock_getres() works, but will ignore its reported
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 // resolution for now. Hopefully as people move to new kernels, this
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 // won't be a problem.
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 struct timespec res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 struct timespec tp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 if (clock_getres_func (CLOCK_MONOTONIC, &res) == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 // yes, monotonic clock is supported
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 _clock_gettime = clock_gettime_func;
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 // close librt if there is no monotonic clock
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 dlclose(handle);
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1411
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 #ifndef SYS_clock_getres
a61af66fc99e Initial load
duke
parents:
diff changeset
1413
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 #if defined(IA32) || defined(AMD64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 #define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229)
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1416 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 #else
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1418 #warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time"
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1419 #define sys_clock_getres(x,y) -1
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1421
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1422 #else
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1423 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1425
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 void os::Linux::fast_thread_clock_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 if (!UseLinuxPosixThreadCPUClocks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 clockid_t clockid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 struct timespec tp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) =
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 (int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
a61af66fc99e Initial load
duke
parents:
diff changeset
1434
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 // Switch to using fast clocks for thread cpu time if
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 // the sys_clock_getres() returns 0 error code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 // Note, that some kernels may support the current thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 // clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 // returned by the pthread_getcpuclockid().
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 // If the fast Posix clocks are supported then the sys_clock_getres()
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 // must return at least tp.tv_sec == 0 which means a resolution
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 // better than 1 sec. This is extra check for reliability.
a61af66fc99e Initial load
duke
parents:
diff changeset
1443
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 if(pthread_getcpuclockid_func &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 pthread_getcpuclockid_func(_main_thread, &clockid) == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 sys_clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1447
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 _supports_fast_thread_cpu_time = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 _pthread_getcpuclockid = pthread_getcpuclockid_func;
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1452
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 jlong os::javaTimeNanos() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 if (Linux::supports_monotonic_clock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 struct timespec tp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 assert(status == 0, "gettime error");
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 timeval time;
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 int status = gettimeofday(&time, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 assert(status != -1, "linux error");
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 return 1000 * usecs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1468
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 if (Linux::supports_monotonic_clock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 info_ptr->max_value = ALL_64_BITS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1472
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 info_ptr->may_skip_backward = false; // not subject to resetting or drifting
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 info_ptr->may_skip_forward = false; // not subject to resetting or drifting
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 // gettimeofday - based on time in seconds since the Epoch thus does not wrap
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 info_ptr->max_value = ALL_64_BITS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1479
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // gettimeofday is a real time clock so it skips
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 info_ptr->may_skip_backward = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 info_ptr->may_skip_forward = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1484
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1487
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 // Return the real, user, and system times in seconds from an
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 // arbitrary fixed point in the past.
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 bool os::getTimesSecs(double* process_real_time,
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 double* process_user_time,
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 double* process_system_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 struct tms ticks;
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 clock_t real_ticks = times(&ticks);
a61af66fc99e Initial load
duke
parents:
diff changeset
1495
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 if (real_ticks == (clock_t) (-1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 double ticks_per_second = (double) clock_tics_per_sec;
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 *process_real_time = ((double) real_ticks) / ticks_per_second;
a61af66fc99e Initial load
duke
parents:
diff changeset
1503
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1507
a61af66fc99e Initial load
duke
parents:
diff changeset
1508
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 char * os::local_time_string(char *buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 struct tm t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 time_t long_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 time(&long_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 localtime_r(&long_time, &t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 t.tm_hour, t.tm_min, t.tm_sec);
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1519
548
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 516
diff changeset
1520 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 516
diff changeset
1521 return localtime_r(clock, res);
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 516
diff changeset
1522 }
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 516
diff changeset
1523
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 // runtime exit support
a61af66fc99e Initial load
duke
parents:
diff changeset
1526
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 // Note: os::shutdown() might be called very early during initialization, or
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 // called from signal handler. Before adding something to os::shutdown(), make
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 // sure it is async-safe and can handle partially initialized VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 void os::shutdown() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1531
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 // allow PerfMemory to attempt cleanup of any persistent resources
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 perfMemory_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1534
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // needs to remove object in file system
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 AttachListener::abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
1537
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 // flush buffered output, finish log files
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 ostream_abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
1540
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 // Check for abort hook
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 abort_hook_t abort_hook = Arguments::abort_hook();
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 if (abort_hook != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 abort_hook();
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1546
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1548
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 // Note: os::abort() might be called very early during initialization, or
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 // called from signal handler. Before adding something to os::abort(), make
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 // sure it is async-safe and can handle partially initialized VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 void os::abort(bool dump_core) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 os::shutdown();
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 if (dump_core) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 fdStream out(defaultStream::output_fd());
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 out.print_raw("Current thread is ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 char buf[16];
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 out.print_raw_cr(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 out.print_raw_cr("Dumping core ...");
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 ::abort(); // dump core
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1565
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 ::exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1568
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 // Die immediately, no exit hook, no abort hook, no cleanup.
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 void os::die() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 // _exit() on LinuxThreads only kills current thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 ::abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1574
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 // unused on linux for now.
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 void os::set_error_file(const char *logfile) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
1577
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1578
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1579 // This method is a copy of JDK's sysGetLastErrorString
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1580 // from src/solaris/hpi/src/system_md.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1581
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1582 size_t os::lasterror(char *buf, size_t len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1583
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1584 if (errno == 0) return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1585
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1586 const char *s = ::strerror(errno);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1587 size_t n = ::strlen(s);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1588 if (n >= len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1589 n = len - 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1590 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1591 ::strncpy(buf, s, n);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1592 buf[n] = '\0';
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1593 return n;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1594 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1595
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 intx os::current_thread_id() { return (intx)pthread_self(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 int os::current_process_id() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1598
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 // Under the old linux thread library, linux gives each thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 // its own process id. Because of this each thread will return
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 // a different pid if this method were to return the result
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 // of getpid(2). Linux provides no api that returns the pid
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 // of the launcher thread for the vm. This implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 // returns a unique pid, the pid of the launcher thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 // that starts the vm 'process'.
a61af66fc99e Initial load
duke
parents:
diff changeset
1606
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 // Under the NPTL, getpid() returns the same pid as the
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 // launcher thread rather than a unique pid per thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 // Use gettid() if you want the old pre NPTL behaviour.
a61af66fc99e Initial load
duke
parents:
diff changeset
1610
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // if you are looking for the result of a call to getpid() that
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // returns a unique pid for the calling thread, then look at the
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 // OSThread::thread_id() method in osThread_linux.hpp file
a61af66fc99e Initial load
duke
parents:
diff changeset
1614
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 return (int)(_initial_pid ? _initial_pid : getpid());
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1617
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // DLL functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1619
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 const char* os::dll_file_extension() { return ".so"; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1621
2130
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2033
diff changeset
1622 // This must be hard coded because it's the system's temporary
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2033
diff changeset
1623 // directory not the java application's temp directory, ala java.io.tmpdir.
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2033
diff changeset
1624 const char* os::get_temp_directory() { return "/tmp"; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1625
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1626 static bool file_exists(const char* filename) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1627 struct stat statbuf;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1628 if (filename == NULL || strlen(filename) == 0) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1629 return false;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1630 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1631 return os::stat(filename, &statbuf) == 0;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1632 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1633
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1634 void os::dll_build_name(char* buffer, size_t buflen,
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1635 const char* pname, const char* fname) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1636 // Copied from libhpi
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1637 const size_t pnamelen = pname ? strlen(pname) : 0;
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1638
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1639 // Quietly truncate on buffer overflow. Should be an error.
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1640 if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1641 *buffer = '\0';
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1642 return;
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1643 }
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1644
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1645 if (pnamelen == 0) {
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1646 snprintf(buffer, buflen, "lib%s.so", fname);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1647 } else if (strchr(pname, *os::path_separator()) != NULL) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1648 int n;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1649 char** pelements = split_path(pname, &n);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1650 for (int i = 0 ; i < n ; i++) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1651 // Really shouldn't be NULL, but check can't hurt
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1652 if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1653 continue; // skip the empty path values
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1654 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1655 snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1656 if (file_exists(buffer)) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1657 break;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1658 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1659 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1660 // release the storage
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1661 for (int i = 0 ; i < n ; i++) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1662 if (pelements[i] != NULL) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1663 FREE_C_HEAP_ARRAY(char, pelements[i]);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1664 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1665 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1666 if (pelements != NULL) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1667 FREE_C_HEAP_ARRAY(char*, pelements);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1668 }
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1669 } else {
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1670 snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1671 }
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1672 }
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1673
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 const char* os::get_current_directory(char *buf, int buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 return getcwd(buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1677
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 // check if addr is inside libjvm[_g].so
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 bool os::address_is_in_vm(address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 static address libjvm_base_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1682
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 if (libjvm_base_addr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 libjvm_base_addr = (address)dlinfo.dli_fbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1688
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 if (dladdr((void *)addr, &dlinfo)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1692
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1695
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 bool os::dll_address_to_function_name(address addr, char *buf,
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 int buflen, int *offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1699
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) {
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1701 if (buf != NULL) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1702 if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1703 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1704 }
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1705 }
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1706 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 return true;
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1708 } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1709 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1710 dlinfo.dli_fname, buf, buflen, offset) == Decoder::no_error) {
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1711 return true;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1712 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 }
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1714
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1715 if (buf != NULL) buf[0] = '\0';
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1716 if (offset != NULL) *offset = -1;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1717 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1719
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 struct _address_to_library_name {
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 address addr; // input : memory address
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 size_t buflen; // size of fname
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 char* fname; // output: library name
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 address base; // library base addr
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1726
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 static int address_to_library_name_callback(struct dl_phdr_info *info,
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 size_t size, void *data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 bool found = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 address libbase = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 struct _address_to_library_name * d = (struct _address_to_library_name *)data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1733
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 // iterate through all loadable segments
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 for (i = 0; i < info->dlpi_phnum; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 address segbase = (address)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 if (info->dlpi_phdr[i].p_type == PT_LOAD) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // base address of a library is the lowest address of its loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 // segments.
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 if (libbase == NULL || libbase > segbase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 libbase = segbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 // see if 'addr' is within current segment
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 if (segbase <= d->addr &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 d->addr < segbase + info->dlpi_phdr[i].p_memsz) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 found = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1750
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 // dlpi_name is NULL or empty if the ELF file is executable, return 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 // so dll_address_to_library_name() can fall through to use dladdr() which
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 // can figure out executable name from argv[0].
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 if (found && info->dlpi_name && info->dlpi_name[0]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 d->base = libbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 if (d->fname) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 jio_snprintf(d->fname, d->buflen, "%s", info->dlpi_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1763
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 bool os::dll_address_to_library_name(address addr, char* buf,
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 int buflen, int* offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 struct _address_to_library_name data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1768
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 // There is a bug in old glibc dladdr() implementation that it could resolve
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 // to wrong library name if the .so file has a base address != NULL. Here
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 // we iterate through the program headers of all loaded libraries to find
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 // out which library 'addr' really belongs to. This workaround can be
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 // removed once the minimum requirement for glibc is moved to 2.3.x.
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 data.addr = addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 data.fname = buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 data.buflen = buflen;
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 data.base = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 int rslt = dl_iterate_phdr(address_to_library_name_callback, (void *)&data);
a61af66fc99e Initial load
duke
parents:
diff changeset
1779
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 if (rslt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 // buf already contains library name
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 if (offset) *offset = addr - data.base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 } else if (dladdr((void*)addr, &dlinfo)){
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 if (offset) *offset = addr - (address)dlinfo.dli_fbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 if (buf) buf[0] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 if (offset) *offset = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1794
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 // Loads .dll/.so and
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 // in case of error it checks if .dll/.so was built for the
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 // same architecture as Hotspot is running on
a61af66fc99e Initial load
duke
parents:
diff changeset
1798
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 void * result= ::dlopen(filename, RTLD_LAZY);
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 if (result != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 // Successful loading
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1806
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 Elf32_Ehdr elf_head;
a61af66fc99e Initial load
duke
parents:
diff changeset
1808
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 // Read system error message into ebuf
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // It may or may not be overwritten below
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 ::strncpy(ebuf, ::dlerror(), ebuflen-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 ebuf[ebuflen-1]='\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 int diag_msg_max_length=ebuflen-strlen(ebuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 char* diag_msg_buf=ebuf+strlen(ebuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1815
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 if (diag_msg_max_length==0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 // No more space in ebuf for additional diagnostics message
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1820
a61af66fc99e Initial load
duke
parents:
diff changeset
1821
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1823
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 if (file_descriptor < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 // Can't open library, report dlerror() message
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1828
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 bool failed_to_read_elf_head=
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 (sizeof(elf_head)!=
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1832
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 ::close(file_descriptor);
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 if (failed_to_read_elf_head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 // file i/o error - report dlerror() msg
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1838
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 typedef struct {
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 Elf32_Half code; // Actual value as defined in elf.h
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 Elf32_Half compat_class; // Compatibility of archs at VM's sense
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 char elf_class; // 32 or 64 bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 char endianess; // MSB or LSB
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 char* name; // String representation
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 } arch_t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1846
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 #ifndef EM_486
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 #define EM_486 6 /* Intel 80486 */
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1850
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 static const arch_t arch_array[]={
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 {EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 {EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 {EM_SPARC, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1860 {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1861 {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1862 {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1863 {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1864 {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1865 {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1866 {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1867 {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1869
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 #if (defined IA32)
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 static Elf32_Half running_arch_code=EM_386;
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 #elif (defined AMD64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 static Elf32_Half running_arch_code=EM_X86_64;
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 #elif (defined IA64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 static Elf32_Half running_arch_code=EM_IA_64;
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 #elif (defined __sparc) && (defined _LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 static Elf32_Half running_arch_code=EM_SPARCV9;
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 #elif (defined __sparc) && (!defined _LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 static Elf32_Half running_arch_code=EM_SPARC;
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 #elif (defined __powerpc64__)
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 static Elf32_Half running_arch_code=EM_PPC64;
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 #elif (defined __powerpc__)
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 static Elf32_Half running_arch_code=EM_PPC;
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1884 #elif (defined ARM)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1885 static Elf32_Half running_arch_code=EM_ARM;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1886 #elif (defined S390)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1887 static Elf32_Half running_arch_code=EM_S390;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1888 #elif (defined ALPHA)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1889 static Elf32_Half running_arch_code=EM_ALPHA;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1890 #elif (defined MIPSEL)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1891 static Elf32_Half running_arch_code=EM_MIPS_RS3_LE;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1892 #elif (defined PARISC)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1893 static Elf32_Half running_arch_code=EM_PARISC;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1894 #elif (defined MIPS)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1895 static Elf32_Half running_arch_code=EM_MIPS;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1896 #elif (defined M68K)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1897 static Elf32_Half running_arch_code=EM_68K;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 #error Method os::dll_load requires that one of following is defined:\
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1900 IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1902
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 // Identify compatability class for VM's architecture and library's architecture
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 // Obtain string descriptions for architectures
a61af66fc99e Initial load
duke
parents:
diff changeset
1905
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 int running_arch_index=-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1908
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 if (running_arch_code == arch_array[i].code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 running_arch_index = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1913 if (lib_arch.code == arch_array[i].code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 lib_arch.compat_class = arch_array[i].compat_class;
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 lib_arch.name = arch_array[i].name;
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1918
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 assert(running_arch_index != -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 "Didn't find running architecture code (running_arch_code) in arch_array");
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 if (running_arch_index == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 // Even though running architecture detection failed
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 // we may still continue with reporting dlerror() message
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1926
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1931
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1932 #ifndef S390
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 }
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1937 #endif // !S390
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1938
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 if ( lib_arch.name!=NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 ::snprintf(diag_msg_buf, diag_msg_max_length-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 " (Possible cause: can't load %s-bit .so on a %s-bit platform)",
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 lib_arch.name, arch_array[running_arch_index].name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 ::snprintf(diag_msg_buf, diag_msg_max_length-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 lib_arch.code,
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 arch_array[running_arch_index].name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1951
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1954
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1955 /*
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1956 * glibc-2.0 libdl is not MT safe. If you are building with any glibc,
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1957 * chances are you might want to run the generated bits against glibc-2.0
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1958 * libdl.so, so always use locking for any version of glibc.
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1959 */
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1960 void* os::dll_lookup(void* handle, const char* name) {
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1961 pthread_mutex_lock(&dl_mutex);
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1962 void* res = dlsym(handle, name);
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1963 pthread_mutex_unlock(&dl_mutex);
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1964 return res;
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1965 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1966
a61af66fc99e Initial load
duke
parents:
diff changeset
1967
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1968 static bool _print_ascii_file(const char* filename, outputStream* st) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1969 int fd = ::open(filename, O_RDONLY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 if (fd == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1973
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 char buf[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 int bytes;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1976 while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 st->print_raw(buf, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1979
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1980 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1981
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1984
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 void os::print_dll_info(outputStream *st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 st->print_cr("Dynamic libraries:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1987
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 char fname[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 pid_t pid = os::Linux::gettid();
a61af66fc99e Initial load
duke
parents:
diff changeset
1990
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 jio_snprintf(fname, sizeof(fname), "/proc/%d/maps", pid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1992
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 if (!_print_ascii_file(fname, st)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 st->print("Can not get library information for pid = %d\n", pid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1997
a61af66fc99e Initial load
duke
parents:
diff changeset
1998
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 void os::print_os_info(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 st->print("OS:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2001
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 // Try to identify popular distros.
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 // Most Linux distributions have /etc/XXX-release file, which contains
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 // the OS version string. Some have more than one /etc/XXX-release file
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 // (e.g. Mandrake has both /etc/mandrake-release and /etc/redhat-release.),
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 // so the order is important.
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 if (!_print_ascii_file("/etc/mandrake-release", st) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 !_print_ascii_file("/etc/sun-release", st) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 !_print_ascii_file("/etc/redhat-release", st) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 !_print_ascii_file("/etc/SuSE-release", st) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 !_print_ascii_file("/etc/turbolinux-release", st) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 !_print_ascii_file("/etc/gentoo-release", st) &&
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2013 !_print_ascii_file("/etc/debian_version", st) &&
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2014 !_print_ascii_file("/etc/ltib-release", st) &&
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2015 !_print_ascii_file("/etc/angstrom-version", st)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 st->print("Linux");
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2019
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 // kernel
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 st->print("uname:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 struct utsname name;
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 uname(&name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 st->print(name.sysname); st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 st->print(name.release); st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 st->print(name.version); st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 st->print(name.machine);
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2029
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 // Print warning if unsafe chroot environment detected
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 if (unsafe_chroot_detected) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 st->print("WARNING!! ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 st->print_cr(unstable_chroot_error);
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2035
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 // libc, pthread
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 st->print("libc:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 st->print(os::Linux::glibc_version()); st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 st->print(os::Linux::libpthread_version()); st->print(" ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 if (os::Linux::is_LinuxThreads()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2044
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 // rlimit
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 st->print("rlimit:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 struct rlimit rlim;
a61af66fc99e Initial load
duke
parents:
diff changeset
2048
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 st->print(" STACK ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 getrlimit(RLIMIT_STACK, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 else st->print("%uk", rlim.rlim_cur >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2053
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 st->print(", CORE ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 getrlimit(RLIMIT_CORE, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 else st->print("%uk", rlim.rlim_cur >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2058
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 st->print(", NPROC ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 getrlimit(RLIMIT_NPROC, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 else st->print("%d", rlim.rlim_cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
2063
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 st->print(", NOFILE ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 getrlimit(RLIMIT_NOFILE, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 else st->print("%d", rlim.rlim_cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
2068
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 st->print(", AS ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 getrlimit(RLIMIT_AS, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 else st->print("%uk", rlim.rlim_cur >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2074
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 // load average
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 st->print("load average:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 double loadavg[3];
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 os::loadavg(loadavg, 3);
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 st->cr();
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2081
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2082 // meminfo
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2083 st->print("\n/proc/meminfo:\n");
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2084 _print_ascii_file("/proc/meminfo", st);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2085 st->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2087
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 void os::print_memory_info(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2089
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 st->print("Memory:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 st->print(" %dk page", os::vm_page_size()>>10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2092
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 // values in struct sysinfo are "unsigned long"
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 struct sysinfo si;
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 sysinfo(&si);
a61af66fc99e Initial load
duke
parents:
diff changeset
2096
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 st->print(", physical " UINT64_FORMAT "k",
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 os::physical_memory() >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 st->print("(" UINT64_FORMAT "k free)",
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 os::available_memory() >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 st->print(", swap " UINT64_FORMAT "k",
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 ((jlong)si.totalswap * si.mem_unit) >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 st->print("(" UINT64_FORMAT "k free)",
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 ((jlong)si.freeswap * si.mem_unit) >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2107
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 // Taken from /usr/include/bits/siginfo.h Supposed to be architecture specific
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 // but they're the same for all the linux arch that we support
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 // and they're the same for solaris but there's no common place to put this.
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR",
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG",
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 "ILL_COPROC", "ILL_BADSTK" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2114
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV",
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES",
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 "FPE_FLTINV", "FPE_FLTSUB", "FPE_FLTDEN" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2118
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2120
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2122
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 void os::print_siginfo(outputStream* st, void* siginfo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 st->print("siginfo:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2125
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 const int buflen = 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 char buf[buflen];
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 siginfo_t *si = (siginfo_t*)siginfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 if (si->si_errno != 0 && strerror_r(si->si_errno, buf, buflen) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 st->print("si_errno=%s", buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 st->print("si_errno=%d", si->si_errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 const int c = si->si_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 assert(c > 0, "unexpected si_code");
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 switch (si->si_signo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 case SIGILL:
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 case SIGFPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 case SIGSEGV:
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 case SIGBUS:
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 st->print(", si_code=%d", si->si_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 // no si_addr
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2158
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 UseSharedSpaces) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 FileMapInfo* mapinfo = FileMapInfo::current_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 if (mapinfo->is_in_shared_space(si->si_addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 st->print("\n\nError accessing class data sharing archive." \
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 " Mapped file inaccessible during execution, " \
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 " possible disk/network problem.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2170
a61af66fc99e Initial load
duke
parents:
diff changeset
2171
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 static void print_signal_handler(outputStream* st, int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 char* buf, size_t buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2174
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 st->print_cr("Signal Handlers:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 print_signal_handler(st, SIGSEGV, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 print_signal_handler(st, SIGBUS , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 print_signal_handler(st, SIGFPE , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 print_signal_handler(st, SIGPIPE, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 print_signal_handler(st, SIGXFSZ, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 print_signal_handler(st, SIGILL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 print_signal_handler(st, SR_signum, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2190
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 static char saved_jvm_path[MAXPATHLEN] = {0};
a61af66fc99e Initial load
duke
parents:
diff changeset
2192
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 // Find the full path to the current module, libjvm.so or libjvm_g.so
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2194 void os::jvm_path(char *buf, jint buflen) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 // Error checking.
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2196 if (buflen < MAXPATHLEN) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 assert(false, "must use a large-enough buffer");
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 buf[0] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 // Lazy resolve the path to current module.
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 if (saved_jvm_path[0] != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 strcpy(buf, saved_jvm_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2206
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 char dli_fname[MAXPATHLEN];
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 bool ret = dll_address_to_library_name(
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 CAST_FROM_FN_PTR(address, os::jvm_path),
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 dli_fname, sizeof(dli_fname), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 assert(ret != 0, "cannot locate libjvm");
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2212 char *rp = realpath(dli_fname, buf);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2213 if (rp == NULL)
513
2328d1d3f8cf 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 477
diff changeset
2214 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2215
2302
da091bb67459 7022037: Pause when exiting if debugger is attached on windows
sla
parents: 2204
diff changeset
2216 if (Arguments::created_by_gamma_launcher()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 // Support for the gamma launcher. Typical value for buf is
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 // the right place in the string, then assume we are installed in a JDK and
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 // we're done. Otherwise, check for a JAVA_HOME environment variable and fix
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 // up the path so it looks like libjvm.so is installed there (append a
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 // fake suffix hotspot/libjvm.so).
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 const char *p = buf + strlen(buf) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 for (int count = 0; p > buf && count < 5; ++count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 for (--p; p > buf && *p != '/'; --p)
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 /* empty */ ;
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2228
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 if (strncmp(p, "/jre/lib/", 9) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 // Look for JAVA_HOME in the environment.
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 char* java_home_var = ::getenv("JAVA_HOME");
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 if (java_home_var != NULL && java_home_var[0] != 0) {
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2233 char* jrelib_p;
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2234 int len;
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2235
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 // Check the current module name "libjvm.so" or "libjvm_g.so".
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 p = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 assert(strstr(p, "/libjvm") == p, "invalid library name");
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 p = strstr(p, "_g") ? "_g" : "";
a61af66fc99e Initial load
duke
parents:
diff changeset
2240
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2241 rp = realpath(java_home_var, buf);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2242 if (rp == NULL)
513
2328d1d3f8cf 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 477
diff changeset
2243 return;
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2244
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2245 // determine if this is a legacy image or modules image
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2246 // modules image doesn't have "jre" subdirectory
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2247 len = strlen(buf);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2248 jrelib_p = buf + len;
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2249 snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2250 if (0 != access(buf, F_OK)) {
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2251 snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2252 }
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2253
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 if (0 == access(buf, F_OK)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 // Use current module name "libjvm[_g].so" instead of
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 // "libjvm"debug_only("_g")".so" since for fastdebug version
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 // we should have "libjvm.so" but debug_only("_g") adds "_g"!
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2258 len = strlen(buf);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2259 snprintf(buf + len, buflen-len, "/hotspot/libjvm%s.so", p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 // Go back to path of .so
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2262 rp = realpath(dli_fname, buf);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2263 if (rp == NULL)
513
2328d1d3f8cf 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 477
diff changeset
2264 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2269
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 strcpy(saved_jvm_path, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2272
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 // no prefix required, not even "_"
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2276
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 void os::print_jni_name_suffix_on(outputStream* st, int args_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 // no suffix required
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2280
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 // sun.misc.Signal support
a61af66fc99e Initial load
duke
parents:
diff changeset
2283
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 static volatile jint sigint_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2285
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 static void
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 UserHandler(int sig, void *siginfo, void *context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 // 4511530 - sem_post is serialized and handled by the manager thread. When
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 // don't want to flood the manager thread with sem_post requests.
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2293
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 // Ctrl-C is pressed during error reporting, likely because the error
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 // handler fails to abort. Let VM die immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 if (sig == SIGINT && is_error_reported()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 os::die();
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2299
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 os::signal_notify(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2302
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 void* os::user_handler() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 return CAST_FROM_FN_PTR(void*, UserHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2306
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 typedef void (*sa_handler_t)(int);
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2311
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 void* os::signal(int signal_number, void* handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 struct sigaction sigAct, oldSigAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
2314
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 sigfillset(&(sigAct.sa_mask));
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 sigAct.sa_flags = SA_RESTART|SA_SIGINFO;
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2318
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 if (sigaction(signal_number, &sigAct, &oldSigAct)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 // -1 means registration failed
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 return (void *)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2323
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2326
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 void os::signal_raise(int signal_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 ::raise(signal_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2330
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 * The following code is moved from os.cpp for making this
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 * code platform specific, which it is by its very nature.
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 */
a61af66fc99e Initial load
duke
parents:
diff changeset
2335
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 // Will be modified when max signal is changed to be dynamic
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 int os::sigexitnum_pd() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 return NSIG;
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2340
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 // a counter for each possible signal value
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 static volatile jint pending_signals[NSIG+1] = { 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2343
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 // Linux(POSIX) specific hand shaking semaphore.
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 static sem_t sig_sem;
a61af66fc99e Initial load
duke
parents:
diff changeset
2346
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 void os::signal_init_pd() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 // Initialize signal structures
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 ::memset((void*)pending_signals, 0, sizeof(pending_signals));
a61af66fc99e Initial load
duke
parents:
diff changeset
2350
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 // Initialize signal semaphore
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 ::sem_init(&sig_sem, 0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2354
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 void os::signal_notify(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 Atomic::inc(&pending_signals[sig]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 ::sem_post(&sig_sem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2359
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 static int check_pending_signals(bool wait) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 Atomic::store(0, &sigint_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 for (int i = 0; i < NSIG + 1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 jint n = pending_signals[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 if (!wait) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 JavaThread *thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 ThreadBlockInVM tbivm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2374
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 bool threadIsSuspended;
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 thread->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 ::sem_wait(&sig_sem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2380
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 if (threadIsSuspended) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 // The semaphore has been incremented, but while we were waiting
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 // another thread suspended us. We don't want to continue running
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 // while suspended because that would surprise the thread that
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 // suspended us.
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 ::sem_post(&sig_sem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2391
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 thread->java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 } while (threadIsSuspended);
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2397
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 int os::signal_lookup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 return check_pending_signals(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2401
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 int os::signal_wait() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 return check_pending_signals(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2405
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 // Virtual Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2408
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 int os::vm_page_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 // Seems redundant as all get out
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 assert(os::Linux::page_size() != -1, "must call os::init");
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 return os::Linux::page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2414
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 // Solaris allocates memory by pages.
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 int os::vm_allocation_granularity() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 assert(os::Linux::page_size() != -1, "must call os::init");
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 return os::Linux::page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2420
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 // Rationale behind this function:
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 // current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 // mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 // samples for JITted code. Here we create private executable mapping over the code cache
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 // and then we can use standard (well, almost, as mapping can change) way to provide
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 // info for the reporting script by storing timestamp and location of symbol
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 void linux_wrap_code(char* base, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 static volatile jint cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2429
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 if (!UseOprofile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2433
1497
96d554193f72 6944822: Fix for 6938627 exposes problem with hard-coded buffer sizes
coleenp
parents: 1353
diff changeset
2434 char buf[PATH_MAX+1];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 int num = Atomic::add(1, &cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2436
1353
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 1325
diff changeset
2437 snprintf(buf, sizeof(buf), "%s/hs-vm-%d-%d",
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 1325
diff changeset
2438 os::get_temp_directory(), os::current_process_id(), num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 unlink(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2440
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2441 int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2442
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 if (fd != -1) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2444 off_t rv = ::lseek(fd, size-2, SEEK_SET);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 if (rv != (off_t)-1) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2446 if (::write(fd, "", 1) == 1) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 mmap(base, size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 PROT_READ|PROT_WRITE|PROT_EXEC,
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 }
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2452 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 unlink(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2456
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 // NOTE: Linux kernel does not really reserve the pages for us.
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 // All it does is to check if there are enough free pages
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 // left at the time of mmap(). This could be a potential
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 // problem.
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2461 bool os::commit_memory(char* addr, size_t size, bool exec) {
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2462 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2463 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 return res != (uintptr_t) MAP_FAILED;
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2467
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2468 // Define MAP_HUGETLB here so we can build HotSpot on old systems.
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2469 #ifndef MAP_HUGETLB
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2470 #define MAP_HUGETLB 0x40000
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2471 #endif
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2472
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2473 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems.
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2474 #ifndef MADV_HUGEPAGE
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2475 #define MADV_HUGEPAGE 14
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2476 #endif
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2477
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2478 bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2479 bool exec) {
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2480 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2481 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2482 uintptr_t res =
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2483 (uintptr_t) ::mmap(addr, size, prot,
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2484 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB,
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2485 -1, 0);
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2486 return res != (uintptr_t) MAP_FAILED;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2487 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2488
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2489 return commit_memory(addr, size, exec);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2491
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2492 void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2493 if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2494 // We don't check the return value: madvise(MADV_HUGEPAGE) may not
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2495 // be supported or the memory may already be backed by huge pages.
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2496 ::madvise(addr, bytes, MADV_HUGEPAGE);
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2497 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2498 }
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2499
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2500 void os::free_memory(char *addr, size_t bytes) {
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2501 ::madvise(addr, bytes, MADV_DONTNEED);
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2502 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2503
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2504 void os::numa_make_global(char *addr, size_t bytes) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2505 Linux::numa_interleave_memory(addr, bytes);
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2506 }
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2507
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2508 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2509 Linux::numa_tonode_memory(addr, bytes, lgrp_hint);
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2510 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2511
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2512 bool os::numa_topology_changed() { return false; }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2513
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2514 size_t os::numa_get_groups_num() {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2515 int max_node = Linux::numa_max_node();
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2516 return max_node > 0 ? max_node + 1 : 1;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2517 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2518
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2519 int os::numa_get_group_id() {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2520 int cpu_id = Linux::sched_getcpu();
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2521 if (cpu_id != -1) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2522 int lgrp_id = Linux::get_node_by_cpu(cpu_id);
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2523 if (lgrp_id != -1) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2524 return lgrp_id;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2525 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2529
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2530 size_t os::numa_get_leaf_groups(int *ids, size_t size) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2531 for (size_t i = 0; i < size; i++) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2532 ids[i] = i;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2533 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2534 return size;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2535 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2536
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 bool os::get_page_info(char *start, page_info* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2540
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 return end;
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2544
2191
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
2545 // Something to do with the numa-aware allocator needs these symbols
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
2546 extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { }
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
2547 extern "C" JNIEXPORT void numa_error(char *where) { }
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
2548 extern "C" JNIEXPORT int fork1() { return fork(); }
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2549
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2550
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2551 // If we are running with libnuma version > 2, then we should
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2552 // be trying to use symbols with versions 1.1
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2553 // If we are running with earlier version, which did not have symbol versions,
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2554 // we should use the base version.
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2555 void* os::Linux::libnuma_dlsym(void* handle, const char *name) {
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2556 void *f = dlvsym(handle, name, "libnuma_1.1");
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2557 if (f == NULL) {
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2558 f = dlsym(handle, name);
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2559 }
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2560 return f;
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2561 }
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2562
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2563 bool os::Linux::libnuma_init() {
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2564 // sched_getcpu() should be in libc.
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2565 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2566 dlsym(RTLD_DEFAULT, "sched_getcpu")));
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2567
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2568 if (sched_getcpu() != -1) { // Does it work?
267
9d6a3a6891f8 6720130: NUMA allocator: The linux version should search for libnuma.so.1
iveresov
parents: 199
diff changeset
2569 void *handle = dlopen("libnuma.so.1", RTLD_LAZY);
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2570 if (handle != NULL) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2571 set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t,
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2572 libnuma_dlsym(handle, "numa_node_to_cpus")));
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2573 set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t,
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2574 libnuma_dlsym(handle, "numa_max_node")));
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2575 set_numa_available(CAST_TO_FN_PTR(numa_available_func_t,
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2576 libnuma_dlsym(handle, "numa_available")));
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2577 set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t,
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2578 libnuma_dlsym(handle, "numa_tonode_memory")));
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2579 set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t,
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2580 libnuma_dlsym(handle, "numa_interleave_memory")));
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2581
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2582
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2583 if (numa_available() != -1) {
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2584 set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes"));
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2585 // Create a cpu -> node mapping
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2586 _cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true);
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2587 rebuild_cpu_to_node_map();
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2588 return true;
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2589 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2590 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2591 }
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2592 return false;
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2593 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2594
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2595 // rebuild_cpu_to_node_map() constructs a table mapping cpud id to node id.
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2596 // The table is later used in get_node_by_cpu().
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2597 void os::Linux::rebuild_cpu_to_node_map() {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2598 const size_t NCPUS = 32768; // Since the buffer size computation is very obscure
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2599 // in libnuma (possible values are starting from 16,
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2600 // and continuing up with every other power of 2, but less
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2601 // than the maximum number of CPUs supported by kernel), and
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2602 // is a subject to change (in libnuma version 2 the requirements
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2603 // are more reasonable) we'll just hardcode the number they use
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2604 // in the library.
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2605 const size_t BitsPerCLong = sizeof(long) * CHAR_BIT;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2606
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2607 size_t cpu_num = os::active_processor_count();
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2608 size_t cpu_map_size = NCPUS / BitsPerCLong;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2609 size_t cpu_map_valid_size =
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2610 MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size);
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2611
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2612 cpu_to_node()->clear();
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2613 cpu_to_node()->at_grow(cpu_num - 1);
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2614 size_t node_num = numa_get_groups_num();
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2615
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2616 unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size);
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2617 for (size_t i = 0; i < node_num; i++) {
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2618 if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2619 for (size_t j = 0; j < cpu_map_valid_size; j++) {
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2620 if (cpu_map[j] != 0) {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2621 for (size_t k = 0; k < BitsPerCLong; k++) {
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2622 if (cpu_map[j] & (1UL << k)) {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2623 cpu_to_node()->at_put(j * BitsPerCLong + k, i);
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2624 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2625 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2626 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2627 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2628 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2629 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2630 FREE_C_HEAP_ARRAY(unsigned long, cpu_map);
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2631 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2632
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2633 int os::Linux::get_node_by_cpu(int cpu_id) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2634 if (cpu_to_node() != NULL && cpu_id >= 0 && cpu_id < cpu_to_node()->length()) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2635 return cpu_to_node()->at(cpu_id);
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2636 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2637 return -1;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2638 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2639
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2640 GrowableArray<int>* os::Linux::_cpu_to_node;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2641 os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2642 os::Linux::numa_node_to_cpus_func_t os::Linux::_numa_node_to_cpus;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2643 os::Linux::numa_max_node_func_t os::Linux::_numa_max_node;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2644 os::Linux::numa_available_func_t os::Linux::_numa_available;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2645 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory;
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2646 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2647 unsigned long* os::Linux::_numa_all_nodes;
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2648
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 bool os::uncommit_memory(char* addr, size_t size) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2650 uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2651 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2652 return res != (uintptr_t) MAP_FAILED;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2654
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2655 // Linux uses a growable mapping for the stack, and if the mapping for
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2656 // the stack guard pages is not removed when we detach a thread the
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2657 // stack cannot grow beyond the pages where the stack guard was
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2658 // mapped. If at some point later in the process the stack expands to
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2659 // that point, the Linux kernel cannot expand the stack any further
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2660 // because the guard pages are in the way, and a segfault occurs.
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2661 //
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2662 // However, it's essential not to split the stack region by unmapping
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2663 // a region (leaving a hole) that's already part of the stack mapping,
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2664 // so if the stack mapping has already grown beyond the guard pages at
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2665 // the time we create them, we have to truncate the stack mapping.
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2666 // So, we need to know the extent of the stack mapping when
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2667 // create_stack_guard_pages() is called.
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2668
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2669 // Find the bounds of the stack mapping. Return true for success.
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2670 //
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2671 // We only need this for stacks that are growable: at the time of
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2672 // writing thread stacks don't use growable mappings (i.e. those
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2673 // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2674 // only applies to the main thread.
2469
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2675
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2676 static
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2677 bool get_stack_bounds(uintptr_t *bottom, uintptr_t *top) {
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2678
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2679 char buf[128];
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2680 int fd, sz;
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2681
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2682 if ((fd = ::open("/proc/self/maps", O_RDONLY)) < 0) {
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2683 return false;
2469
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2684 }
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2685
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2686 const char kw[] = "[stack]";
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2687 const int kwlen = sizeof(kw)-1;
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2688
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2689 // Address part of /proc/self/maps couldn't be more than 128 bytes
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2690 while ((sz = os::get_line_chars(fd, buf, sizeof(buf))) > 0) {
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2691 if (sz > kwlen && ::memcmp(buf+sz-kwlen, kw, kwlen) == 0) {
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2692 // Extract addresses
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2693 if (sscanf(buf, "%" SCNxPTR "-%" SCNxPTR, bottom, top) == 2) {
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2694 uintptr_t sp = (uintptr_t) __builtin_frame_address(0);
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2695 if (sp >= *bottom && sp <= *top) {
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2696 ::close(fd);
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2697 return true;
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2698 }
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2699 }
2469
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2700 }
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2701 }
2469
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2702
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2703 ::close(fd);
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2704 return false;
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2705 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2706
2469
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
2707
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2708 // If the (growable) stack mapping already extends beyond the point
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2709 // where we're going to put our guard pages, truncate the mapping at
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2710 // that point by munmap()ping it. This ensures that when we later
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2711 // munmap() the guard pages we don't leave a hole in the stack
1750
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2712 // mapping. This only affects the main/initial thread, but guard
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2713 // against future OS changes
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2714 bool os::create_stack_guard_pages(char* addr, size_t size) {
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2715 uintptr_t stack_extent, stack_base;
1750
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2716 bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true);
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2717 if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) {
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2718 assert(os::Linux::is_initial_thread(),
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2719 "growable stack in non-initial thread");
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2720 if (stack_extent < (uintptr_t)addr)
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2721 ::munmap((void*)stack_extent, (uintptr_t)addr - stack_extent);
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2722 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2723
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2724 return os::commit_memory(addr, size);
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2725 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2726
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2727 // If this is a growable mapping, remove the guard pages entirely by
1750
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2728 // munmap()ping them. If not, just call uncommit_memory(). This only
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2729 // affects the main/initial thread, but guard against future OS changes
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2730 bool os::remove_stack_guard_pages(char* addr, size_t size) {
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2731 uintptr_t stack_extent, stack_base;
1750
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2732 bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true);
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2733 if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) {
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2734 assert(os::Linux::is_initial_thread(),
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2735 "growable stack in non-initial thread");
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
2736
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2737 return ::munmap(addr, size) == 0;
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2738 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2739
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2740 return os::uncommit_memory(addr, size);
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2741 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2742
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 static address _highest_vm_reserved_address = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2744
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 // If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 // at 'requested_addr'. If there are existing memory mappings at the same
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 // location, however, they will be overwritten. If 'fixed' is false,
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 // 'requested_addr' is only treated as a hint, the return value may or
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 // may not start from the requested address. Unlike Linux mmap(), this
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 // function returns NULL to indicate failure.
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 char * addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 int flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
2754
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS;
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 if (fixed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 assert((uintptr_t)requested_addr % os::Linux::page_size() == 0, "unaligned address");
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 flags |= MAP_FIXED;
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2760
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2761 // Map uncommitted pages PROT_READ and PROT_WRITE, change access
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2762 // to PROT_EXEC if executable when we commit the page.
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2763 addr = (char*)::mmap(requested_addr, bytes, PROT_READ|PROT_WRITE,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 flags, -1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2765
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 if (addr != MAP_FAILED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 // anon_mmap() should only get called during VM initialization,
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 // don't need lock (actually we can skip locking even it can be called
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 // from multiple threads, because _highest_vm_reserved_address is just a
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 // hint about the upper limit of non-stack memory regions.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 if ((address)addr + bytes > _highest_vm_reserved_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 _highest_vm_reserved_address = (address)addr + bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2775
a61af66fc99e Initial load
duke
parents:
diff changeset
2776 return addr == MAP_FAILED ? NULL : addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2778
a61af66fc99e Initial load
duke
parents:
diff changeset
2779 // Don't update _highest_vm_reserved_address, because there might be memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 // regions above addr + size. If so, releasing a memory region only creates
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 // a hole in the address space, it doesn't help prevent heap-stack collision.
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 static int anon_munmap(char * addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 return ::munmap(addr, size) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2786
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 char* os::reserve_memory(size_t bytes, char* requested_addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 size_t alignment_hint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2791
a61af66fc99e Initial load
duke
parents:
diff changeset
2792 bool os::release_memory(char* addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 return anon_munmap(addr, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2795
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 static address highest_vm_reserved_address() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 return _highest_vm_reserved_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2799
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 static bool linux_mprotect(char* addr, size_t size, int prot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 // Linux wants the mprotect address argument to be page aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 char* bottom = (char*)align_size_down((intptr_t)addr, os::Linux::page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
2803
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 // According to SUSv3, mprotect() should only be used with mappings
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 // established by mmap(), and mmap() always maps whole pages. Unaligned
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 // 'addr' likely indicates problem in the VM (e.g. trying to change
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 // protection of malloc'ed or statically allocated memory). Check the
a61af66fc99e Initial load
duke
parents:
diff changeset
2808 // caller if you hit this assert.
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 assert(addr == bottom, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2810
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Linux::page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 return ::mprotect(bottom, size, prot) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2814
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2815 // Set protections specified
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2816 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2817 bool is_committed) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2818 unsigned int p = 0;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2819 switch (prot) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2820 case MEM_PROT_NONE: p = PROT_NONE; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2821 case MEM_PROT_READ: p = PROT_READ; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2822 case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2823 case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2824 default:
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2825 ShouldNotReachHere();
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2826 }
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2827 // is_committed is unused.
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
2828 return linux_mprotect(addr, bytes, p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2830
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 bool os::guard_memory(char* addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 return linux_mprotect(addr, size, PROT_NONE);
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2834
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 bool os::unguard_memory(char* addr, size_t size) {
477
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 462
diff changeset
2836 return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2838
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2839 bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2840 bool result = false;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2841 void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE,
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2842 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2843 -1, 0);
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2844
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2845 if (p != (void *) -1) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2846 // We don't know if this really is a huge page or not.
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2847 FILE *fp = fopen("/proc/self/maps", "r");
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2848 if (fp) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2849 while (!feof(fp)) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2850 char chars[257];
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2851 long x = 0;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2852 if (fgets(chars, sizeof(chars), fp)) {
3358
97b64f73103b 7043564: compile warning and copyright fixes
iveresov
parents: 3318
diff changeset
2853 if (sscanf(chars, "%lx-%*x", &x) == 1
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2854 && x == (long)p) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2855 if (strstr (chars, "hugepage")) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2856 result = true;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2857 break;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2858 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2859 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2860 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2861 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2862 fclose(fp);
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2863 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2864 munmap (p, page_size);
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2865 if (result)
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2866 return true;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2867 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2868
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2869 if (warn) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2870 warning("HugeTLBFS is not supported by the operating system.");
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2871 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2872
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2873 return result;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2874 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2875
2204
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2876 /*
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2877 * Set the coredump_filter bits to include largepages in core dump (bit 6)
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2878 *
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2879 * From the coredump_filter documentation:
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2880 *
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2881 * - (bit 0) anonymous private memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2882 * - (bit 1) anonymous shared memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2883 * - (bit 2) file-backed private memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2884 * - (bit 3) file-backed shared memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2885 * - (bit 4) ELF header pages in file-backed private memory areas (it is
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2886 * effective only if the bit 2 is cleared)
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2887 * - (bit 5) hugetlb private memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2888 * - (bit 6) hugetlb shared memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2889 */
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2890 static void set_coredump_filter(void) {
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2891 FILE *f;
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2892 long cdm;
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2893
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2894 if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2895 return;
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2896 }
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2897
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2898 if (fscanf(f, "%lx", &cdm) != 1) {
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2899 fclose(f);
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2900 return;
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2901 }
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2902
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2903 rewind(f);
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2904
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2905 if ((cdm & LARGEPAGES_BIT) == 0) {
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2906 cdm |= LARGEPAGES_BIT;
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2907 fprintf(f, "%#lx", cdm);
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2908 }
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2909
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2910 fclose(f);
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2911 }
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2912
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 // Large page support
a61af66fc99e Initial load
duke
parents:
diff changeset
2914
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 static size_t _large_page_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2916
3318
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
2917 void os::large_page_init() {
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2918 if (!UseLargePages) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2919 UseHugeTLBFS = false;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2920 UseSHM = false;
3318
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
2921 return;
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2922 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2923
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2924 if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) {
3318
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
2925 // If UseLargePages is specified on the command line try both methods,
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
2926 // if it's default, then try only HugeTLBFS.
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
2927 if (FLAG_IS_DEFAULT(UseLargePages)) {
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
2928 UseHugeTLBFS = true;
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
2929 } else {
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
2930 UseHugeTLBFS = UseSHM = true;
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
2931 }
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2932 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2933
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 if (LargePageSizeInBytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 _large_page_size = LargePageSizeInBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 // large_page_size on Linux is used to round up heap size. x86 uses either
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 // page as large as 256M.
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 // Here we try to figure out page size by parsing /proc/meminfo and looking
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 // for a line with the following format:
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 // Hugepagesize: 2048 kB
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 // If we can't determine the value (e.g. /proc is not mounted, or the text
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 // format has been changed), we'll use the largest page size supported by
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 // the processor.
a61af66fc99e Initial load
duke
parents:
diff changeset
2949
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
2950 #ifndef ZERO
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2951 _large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2952 ARM_ONLY(2 * M) PPC_ONLY(4 * M);
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
2953 #endif // ZERO
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2954
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 FILE *fp = fopen("/proc/meminfo", "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 if (fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 while (!feof(fp)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 int x = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 char buf[16];
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 _large_page_size = x * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 // skip to next line
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 int ch = fgetc(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 if (ch == EOF || ch == (int)'\n') break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2976
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2977 // print a warning if any large page related flag is specified on command line
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2978 bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2979
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 const size_t default_page_size = (size_t)Linux::page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 if (_large_page_size > default_page_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 _page_sizes[0] = _large_page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 _page_sizes[1] = default_page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 _page_sizes[2] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 }
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2986 UseHugeTLBFS = UseHugeTLBFS &&
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2987 Linux::hugetlbfs_sanity_check(warn_on_failure, _large_page_size);
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2988
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2989 if (UseHugeTLBFS)
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2990 UseSHM = false;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2991
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2992 UseLargePages = UseHugeTLBFS || UseSHM;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2993
2204
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
2994 set_coredump_filter();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2996
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 #ifndef SHM_HUGETLB
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 #define SHM_HUGETLB 04000
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3000
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
3001 char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) {
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
3002 // "exec" is passed in but not used. Creating the shared image for
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
3003 // the code cache doesn't have an SHM_X executable permission to check.
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3004 assert(UseLargePages && UseSHM, "only for SHM large pages");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3005
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 key_t key = IPC_PRIVATE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 char *addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3008
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 bool warn_on_failure = UseLargePages &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 (!FLAG_IS_DEFAULT(UseLargePages) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 !FLAG_IS_DEFAULT(LargePageSizeInBytes)
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 char msg[128];
a61af66fc99e Initial load
duke
parents:
diff changeset
3014
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 // Create a large shared memory region to attach to based on size.
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 // Currently, size is the total size of the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
3017 int shmid = shmget(key, bytes, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 if (shmid == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 // Possible reasons for shmget failure:
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 // 1. shmmax is too small for Java heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 // > check shmmax value: cat /proc/sys/kernel/shmmax
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 // > increase shmmax value: echo "0xffffffff" > /proc/sys/kernel/shmmax
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 // 2. not enough large page memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 // > check available large pages: cat /proc/meminfo
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 // > increase amount of large pages:
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 // echo new_value > /proc/sys/vm/nr_hugepages
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 // Note 1: different Linux may use different name for this property,
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 // e.g. on Redhat AS-3 it is "hugetlb_pool".
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 // Note 2: it's possible there's enough physical memory available but
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 // they are so fragmented after a long run that they can't
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 // coalesce into large pages. Try to reserve large pages when
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 // the system is still "fresh".
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 if (warn_on_failure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 warning(msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3039
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 // attach to the region
1537
79bf863697eb 6951686: Using large pages on Linux prevents zero based compressed oops
kvn
parents: 1500
diff changeset
3041 addr = (char*)shmat(shmid, req_addr, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 int err = errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3043
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 // Remove shmid. If shmat() is successful, the actual shared memory segment
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 // will be deleted when it's detached by shmdt() or when the process
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 // terminates. If shmat() is not successful this will remove the shared
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 // segment immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 shmctl(shmid, IPC_RMID, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3049
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 if ((intptr_t)addr == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 if (warn_on_failure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 warning(msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3057
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3060
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 bool os::release_memory_special(char* base, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 // detaching the SHM segment will also delete it, see reserve_memory_special()
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 int rslt = shmdt(base);
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 return rslt == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3066
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 size_t os::large_page_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 return _large_page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3070
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3071 // HugeTLBFS allows application to commit large page memory on demand;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3072 // with SysV SHM the entire memory region must be allocated as shared
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3073 // memory.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 bool os::can_commit_large_page_memory() {
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3075 return UseHugeTLBFS;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3077
79
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 62
diff changeset
3078 bool os::can_execute_large_page_memory() {
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3079 return UseHugeTLBFS;
79
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 62
diff changeset
3080 }
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 62
diff changeset
3081
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 // Reserve memory at an arbitrary address, only if that area is
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 // available (and not reserved for something else).
a61af66fc99e Initial load
duke
parents:
diff changeset
3084
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 const int max_tries = 10;
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 char* base[max_tries];
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 size_t size[max_tries];
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 const size_t gap = 0x000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
3090
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 // Assert only that the size is a multiple of the page size, since
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 // that's all that mmap requires, and since that's all we really know
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 // about at this low abstraction level. If we need higher alignment,
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 // we can either pass an alignment to this method or verify alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 // in one of the methods further up the call chain. See bug 5044738.
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
a61af66fc99e Initial load
duke
parents:
diff changeset
3097
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 // Repeatedly allocate blocks until the block is allocated at the
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 // right spot. Give up after max_tries. Note that reserve_memory() will
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 // automatically update _highest_vm_reserved_address if the call is
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 // successful. The variable tracks the highest memory address every reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 // by JVM. It is used to detect heap-stack collision if running with
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 // fixed-stack LinuxThreads. Because here we may attempt to reserve more
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 // space than needed, it could confuse the collision detecting code. To
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 // solve the problem, save current _highest_vm_reserved_address and
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 // calculate the correct value before return.
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 address old_highest = _highest_vm_reserved_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
3108
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 // Linux mmap allows caller to pass an address as hint; give it a try first,
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 // if kernel honors the hint then we can return immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 char * addr = anon_mmap(requested_addr, bytes, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 if (addr == requested_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 return requested_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3115
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 if (addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 // mmap() is successful but it fails to reserve at the requested address
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 anon_munmap(addr, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3120
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 for (i = 0; i < max_tries; ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 base[i] = reserve_memory(bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3124
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 if (base[i] != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 // Is this the block we wanted?
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 if (base[i] == requested_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 size[i] = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3131
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 // Does this overlap the block we wanted? Give back the overlapped
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 // parts and try again.
a61af66fc99e Initial load
duke
parents:
diff changeset
3134
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 size_t top_overlap = requested_addr + (bytes + gap) - base[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 if (top_overlap >= 0 && top_overlap < bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 unmap_memory(base[i], top_overlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 base[i] += top_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 size[i] = bytes - top_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 size_t bottom_overlap = base[i] + bytes - requested_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 if (bottom_overlap >= 0 && bottom_overlap < bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 unmap_memory(requested_addr, bottom_overlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 size[i] = bytes - bottom_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 size[i] = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3151
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 // Give back the unused reserved pieces.
a61af66fc99e Initial load
duke
parents:
diff changeset
3153
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 for (int j = 0; j < i; ++j) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 if (base[j] != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 unmap_memory(base[j], size[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3159
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 if (i < max_tries) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 _highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 return requested_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3163 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 _highest_vm_reserved_address = old_highest;
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3168
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 size_t os::read(int fd, void *buf, unsigned int nBytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 return ::read(fd, buf, nBytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3172
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 // TODO-FIXME: reconcile Solaris' os::sleep with the linux variation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 // Solaris uses poll(), linux uses park().
a61af66fc99e Initial load
duke
parents:
diff changeset
3175 // Poll() is likely a better choice, assuming that Thread.interrupt()
a61af66fc99e Initial load
duke
parents:
diff changeset
3176 // generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
a61af66fc99e Initial load
duke
parents:
diff changeset
3177 // SIGSEGV, see 4355769.
a61af66fc99e Initial load
duke
parents:
diff changeset
3178
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 const int NANOSECS_PER_MILLISECS = 1000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
3180
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 int os::sleep(Thread* thread, jlong millis, bool interruptible) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 assert(thread == Thread::current(), "thread consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3183
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 ParkEvent * const slp = thread->_SleepEvent ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 slp->reset() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 OrderAccess::fence() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3187
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 if (interruptible) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3189 jlong prevtime = javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
3190
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3192 if (os::is_interrupted(thread, true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 return OS_INTRPT;
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3195
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 jlong newtime = javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
3197
a61af66fc99e Initial load
duke
parents:
diff changeset
3198 if (newtime - prevtime < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 // time moving backwards, should only happen if no monotonic clock
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 // not a guarantee() because JVM should not abort on kernel/glibc bugs
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 assert(!Linux::supports_monotonic_clock(), "time moving backwards");
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISECS;
a61af66fc99e Initial load
duke
parents:
diff changeset
3204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3205
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 if(millis <= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3209
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 prevtime = newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3211
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 assert(thread->is_Java_thread(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 JavaThread *jt = (JavaThread *) thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 ThreadBlockInVM tbivm(jt);
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
3217
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 jt->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 // cleared by handle_special_suspend_equivalent_condition() or
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 // java_suspend_self() via check_and_wait_while_suspended()
a61af66fc99e Initial load
duke
parents:
diff changeset
3221
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 slp->park(millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
3223
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 jt->check_and_wait_while_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3228 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 jlong prevtime = javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
3231
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 // the 1st iteration ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 jlong newtime = javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
3236
a61af66fc99e Initial load
duke
parents:
diff changeset
3237 if (newtime - prevtime < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 // time moving backwards, should only happen if no monotonic clock
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 // not a guarantee() because JVM should not abort on kernel/glibc bugs
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 assert(!Linux::supports_monotonic_clock(), "time moving backwards");
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISECS;
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3244
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 if(millis <= 0) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3246
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 prevtime = newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 slp->park(millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 return OS_OK ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3253
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 int os::naked_sleep() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3255 // %% make the sleep time an integer flag. for now use 1 millisec.
a61af66fc99e Initial load
duke
parents:
diff changeset
3256 return os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3258
a61af66fc99e Initial load
duke
parents:
diff changeset
3259 // Sleep forever; naked call to OS-specific sleep; use with CAUTION
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 void os::infinite_sleep() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3261 while (true) { // sleep forever ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3262 ::sleep(100); // ... 100 seconds at a time
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3265
a61af66fc99e Initial load
duke
parents:
diff changeset
3266 // Used to convert frequent JVM_Yield() to nops
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 bool os::dont_yield() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 return DontYieldALot;
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3270
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 void os::yield() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3272 sched_yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
3273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3274
a61af66fc99e Initial load
duke
parents:
diff changeset
3275 os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;}
a61af66fc99e Initial load
duke
parents:
diff changeset
3276
a61af66fc99e Initial load
duke
parents:
diff changeset
3277 void os::yield_all(int attempts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3278 // Yields to all threads, including threads with lower priorities
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 // Threads on Linux are all with same priority. The Solaris style
a61af66fc99e Initial load
duke
parents:
diff changeset
3280 // os::yield_all() with nanosleep(1ms) is not necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 sched_yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
3282 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3283
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 // Called from the tight loops to possibly influence time-sharing heuristics
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 void os::loop_breaker(int attempts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3286 os::yield_all(attempts);
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3288
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 // thread priority support
a61af66fc99e Initial load
duke
parents:
diff changeset
3291
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 // Note: Normal Linux applications are run with SCHED_OTHER policy. SCHED_OTHER
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 // only supports dynamic priority, static priority must be zero. For real-time
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 // applications, Linux supports SCHED_RR which allows static priority (1-99).
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 // However, for large multi-threaded applications, SCHED_RR is not only slower
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 // than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 // of 5 runs - Sep 2005).
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 // The following code actually changes the niceness of kernel-thread/LWP. It
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 // has an assumption that setpriority() only modifies one kernel-thread/LWP,
a61af66fc99e Initial load
duke
parents:
diff changeset
3301 // not the entire user process, and user level threads are 1:1 mapped to kernel
a61af66fc99e Initial load
duke
parents:
diff changeset
3302 // threads. It has always been the case, but could change in the future. For
a61af66fc99e Initial load
duke
parents:
diff changeset
3303 // this reason, the code should not be used as default (ThreadPriorityPolicy=0).
a61af66fc99e Initial load
duke
parents:
diff changeset
3304 // It is only used when ThreadPriorityPolicy=1 and requires root privilege.
a61af66fc99e Initial load
duke
parents:
diff changeset
3305
a61af66fc99e Initial load
duke
parents:
diff changeset
3306 int os::java_to_os_priority[MaxPriority + 1] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
3307 19, // 0 Entry should never be used
a61af66fc99e Initial load
duke
parents:
diff changeset
3308
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 4, // 1 MinPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
3310 3, // 2
a61af66fc99e Initial load
duke
parents:
diff changeset
3311 2, // 3
a61af66fc99e Initial load
duke
parents:
diff changeset
3312
a61af66fc99e Initial load
duke
parents:
diff changeset
3313 1, // 4
a61af66fc99e Initial load
duke
parents:
diff changeset
3314 0, // 5 NormPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
3315 -1, // 6
a61af66fc99e Initial load
duke
parents:
diff changeset
3316
a61af66fc99e Initial load
duke
parents:
diff changeset
3317 -2, // 7
a61af66fc99e Initial load
duke
parents:
diff changeset
3318 -3, // 8
a61af66fc99e Initial load
duke
parents:
diff changeset
3319 -4, // 9 NearMaxPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
3320
a61af66fc99e Initial load
duke
parents:
diff changeset
3321 -5 // 10 MaxPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3323
a61af66fc99e Initial load
duke
parents:
diff changeset
3324 static int prio_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 if (ThreadPriorityPolicy == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3326 // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 // if effective uid is not root. Perhaps, a more elegant way of doing
a61af66fc99e Initial load
duke
parents:
diff changeset
3328 // this is to test CAP_SYS_NICE capability, but that will require libcap.so
a61af66fc99e Initial load
duke
parents:
diff changeset
3329 if (geteuid() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3330 if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3331 warning("-XX:ThreadPriorityPolicy requires root privilege on Linux");
a61af66fc99e Initial load
duke
parents:
diff changeset
3332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3333 ThreadPriorityPolicy = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3338
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 OSReturn os::set_native_priority(Thread* thread, int newpri) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3341
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 return (ret == 0) ? OS_OK : OS_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3345
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3347 if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 *priority_ptr = java_to_os_priority[NormPriority];
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3351
a61af66fc99e Initial load
duke
parents:
diff changeset
3352 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 *priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
3354 return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3356
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 // Hint to the underlying OS that a task switch would not be good.
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 // Void return because it's a hint and can fail.
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 void os::hint_no_preempt() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
3360
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
3362 // suspend/resume support
a61af66fc99e Initial load
duke
parents:
diff changeset
3363
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 // the low-level signal-based suspend/resume support is a remnant from the
a61af66fc99e Initial load
duke
parents:
diff changeset
3365 // old VM-suspension that used to be for java-suspension, safepoints etc,
a61af66fc99e Initial load
duke
parents:
diff changeset
3366 // within hotspot. Now there is a single use-case for this:
a61af66fc99e Initial load
duke
parents:
diff changeset
3367 // - calling get_thread_pc() on the VMThread by the flat-profiler task
a61af66fc99e Initial load
duke
parents:
diff changeset
3368 // that runs in the watcher thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
3369 // The remaining code is greatly simplified from the more general suspension
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 // code that used to be used.
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 // The protocol is quite simple:
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 // - suspend:
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 // - sends a signal to the target thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 // - polls the suspend state of the osthread using a yield loop
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 // - target thread signal handler (SR_handler) sets suspend state
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 // and blocks in sigsuspend until continued
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 // - resume:
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 // - sets target osthread state to continue
a61af66fc99e Initial load
duke
parents:
diff changeset
3380 // - sends signal to end the sigsuspend loop in the SR_handler
a61af66fc99e Initial load
duke
parents:
diff changeset
3381 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3382 // Note that the SR_lock plays no role in this suspend/resume protocol.
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3384
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 static void resume_clear_context(OSThread *osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 osthread->set_ucontext(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3387 osthread->set_siginfo(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3388
a61af66fc99e Initial load
duke
parents:
diff changeset
3389 // notify the suspend action is completed, we have now resumed
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 osthread->sr.clear_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
3391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3392
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 osthread->set_ucontext(context);
a61af66fc99e Initial load
duke
parents:
diff changeset
3395 osthread->set_siginfo(siginfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3397
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 // Handler function invoked when a thread's execution is suspended or
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 // resumed. We have to be careful that only async-safe functions are
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 // called here (Note: most pthread functions are not async safe and
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 // should be avoided.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3404 // Note: sigwait() is a more natural fit than sigsuspend() from an
a61af66fc99e Initial load
duke
parents:
diff changeset
3405 // interface point of view, but sigwait() prevents the signal hander
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 // from being run. libpthread would get very confused by not having
a61af66fc99e Initial load
duke
parents:
diff changeset
3407 // its signal handlers run and prevents sigwait()'s use with the
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 // mutex granting granting signal.
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3410 // Currently only ever called on the VMThread
a61af66fc99e Initial load
duke
parents:
diff changeset
3411 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3412 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 // Save and restore errno to avoid confusing native code with EINTR
a61af66fc99e Initial load
duke
parents:
diff changeset
3414 // after sigsuspend.
a61af66fc99e Initial load
duke
parents:
diff changeset
3415 int old_errno = errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3416
a61af66fc99e Initial load
duke
parents:
diff changeset
3417 Thread* thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
3418 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
3419 assert(thread->is_VM_thread(), "Must be VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
3420 // read current suspend action
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 int action = osthread->sr.suspend_action();
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 if (action == SR_SUSPEND) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3423 suspend_save_context(osthread, siginfo, context);
a61af66fc99e Initial load
duke
parents:
diff changeset
3424
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 // Notify the suspend action is about to be completed. do_suspend()
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 // waits until SR_SUSPENDED is set and then returns. We will wait
a61af66fc99e Initial load
duke
parents:
diff changeset
3427 // here for a resume signal and that completes the suspend-other
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 // action. do_suspend/do_resume is always called as a pair from
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 // the same thread - so there are no races
a61af66fc99e Initial load
duke
parents:
diff changeset
3430
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 // notify the caller
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 osthread->sr.set_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
3433
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 sigset_t suspend_set; // signals for sigsuspend()
a61af66fc99e Initial load
duke
parents:
diff changeset
3435
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 // get current set of blocked signals and unblock resume signal
a61af66fc99e Initial load
duke
parents:
diff changeset
3437 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 sigdelset(&suspend_set, SR_signum);
a61af66fc99e Initial load
duke
parents:
diff changeset
3439
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 // wait here until we are resumed
a61af66fc99e Initial load
duke
parents:
diff changeset
3441 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 sigsuspend(&suspend_set);
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 // ignore all returns until we get a resume signal
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 } while (osthread->sr.suspend_action() != SR_CONTINUE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3445
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 resume_clear_context(osthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
3447
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 assert(action == SR_CONTINUE, "unexpected sr action");
a61af66fc99e Initial load
duke
parents:
diff changeset
3450 // nothing special to do - just leave the handler
a61af66fc99e Initial load
duke
parents:
diff changeset
3451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3452
a61af66fc99e Initial load
duke
parents:
diff changeset
3453 errno = old_errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3455
a61af66fc99e Initial load
duke
parents:
diff changeset
3456
a61af66fc99e Initial load
duke
parents:
diff changeset
3457 static int SR_initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3458 struct sigaction act;
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 char *s;
a61af66fc99e Initial load
duke
parents:
diff changeset
3460 /* Get signal number to use for suspend/resume */
a61af66fc99e Initial load
duke
parents:
diff changeset
3461 if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 int sig = ::strtol(s, 0, 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
3463 if (sig > 0 || sig < _NSIG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3464 SR_signum = sig;
a61af66fc99e Initial load
duke
parents:
diff changeset
3465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3467
a61af66fc99e Initial load
duke
parents:
diff changeset
3468 assert(SR_signum > SIGSEGV && SR_signum > SIGBUS,
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");
a61af66fc99e Initial load
duke
parents:
diff changeset
3470
a61af66fc99e Initial load
duke
parents:
diff changeset
3471 sigemptyset(&SR_sigset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3472 sigaddset(&SR_sigset, SR_signum);
a61af66fc99e Initial load
duke
parents:
diff changeset
3473
a61af66fc99e Initial load
duke
parents:
diff changeset
3474 /* Set up signal handler for suspend/resume */
a61af66fc99e Initial load
duke
parents:
diff changeset
3475 act.sa_flags = SA_RESTART|SA_SIGINFO;
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 act.sa_handler = (void (*)(int)) SR_handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
3477
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 // SR_signum is blocked by default.
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 // 4528190 - We also need to block pthread restart signal (32 on all
a61af66fc99e Initial load
duke
parents:
diff changeset
3480 // supported Linux platforms). Note that LinuxThreads need to block
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 // this signal for all threads to work properly. So we don't have
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 // to use hard-coded signal number when setting up the mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
3484
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 if (sigaction(SR_signum, &act, 0) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3488
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 // Save signal flag
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 os::Linux::set_our_sigflags(SR_signum, act.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
3491 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3493
a61af66fc99e Initial load
duke
parents:
diff changeset
3494 static int SR_finalize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3495 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3497
a61af66fc99e Initial load
duke
parents:
diff changeset
3498
a61af66fc99e Initial load
duke
parents:
diff changeset
3499 // returns true on success and false on error - really an error is fatal
a61af66fc99e Initial load
duke
parents:
diff changeset
3500 // but this seems the normal response to library errors
a61af66fc99e Initial load
duke
parents:
diff changeset
3501 static bool do_suspend(OSThread* osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 // mark as suspended and send signal
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 osthread->sr.set_suspend_action(SR_SUSPEND);
a61af66fc99e Initial load
duke
parents:
diff changeset
3504 int status = pthread_kill(osthread->pthread_id(), SR_signum);
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 assert_status(status == 0, status, "pthread_kill");
a61af66fc99e Initial load
duke
parents:
diff changeset
3506
a61af66fc99e Initial load
duke
parents:
diff changeset
3507 // check status and wait until notified of suspension
a61af66fc99e Initial load
duke
parents:
diff changeset
3508 if (status == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3509 for (int i = 0; !osthread->sr.is_suspended(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 os::yield_all(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 osthread->sr.set_suspend_action(SR_NONE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3513 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 osthread->sr.set_suspend_action(SR_NONE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3517 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3520
a61af66fc99e Initial load
duke
parents:
diff changeset
3521 static void do_resume(OSThread* osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 assert(osthread->sr.is_suspended(), "thread should be suspended");
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 osthread->sr.set_suspend_action(SR_CONTINUE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3524
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 int status = pthread_kill(osthread->pthread_id(), SR_signum);
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 assert_status(status == 0, status, "pthread_kill");
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 // check status and wait unit notified of resumption
a61af66fc99e Initial load
duke
parents:
diff changeset
3528 if (status == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 for (int i = 0; osthread->sr.is_suspended(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 os::yield_all(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 osthread->sr.set_suspend_action(SR_NONE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3535
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 // interrupt support
a61af66fc99e Initial load
duke
parents:
diff changeset
3538
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 void os::interrupt(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 assert(Thread::current() == thread || Threads_lock->owned_by_self(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 "possibility of dangling Thread pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
3542
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
3544
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 if (!osthread->interrupted()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3546 osthread->set_interrupted(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 // More than one thread can get here with the same value of osthread,
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 // resulting in multiple notifications. We do, however, want the store
a61af66fc99e Initial load
duke
parents:
diff changeset
3549 // to interrupted() to be visible to other threads before we execute unpark().
a61af66fc99e Initial load
duke
parents:
diff changeset
3550 OrderAccess::fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 ParkEvent * const slp = thread->_SleepEvent ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 if (slp != NULL) slp->unpark() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3554
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 // For JSR166. Unpark even if interrupt status already was set
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 if (thread->is_Java_thread())
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 ((JavaThread*)thread)->parker()->unpark();
a61af66fc99e Initial load
duke
parents:
diff changeset
3558
a61af66fc99e Initial load
duke
parents:
diff changeset
3559 ParkEvent * ev = thread->_ParkEvent ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 if (ev != NULL) ev->unpark() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3561
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3563
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 assert(Thread::current() == thread || Threads_lock->owned_by_self(),
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 "possibility of dangling Thread pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
3567
a61af66fc99e Initial load
duke
parents:
diff changeset
3568 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
3569
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 bool interrupted = osthread->interrupted();
a61af66fc99e Initial load
duke
parents:
diff changeset
3571
a61af66fc99e Initial load
duke
parents:
diff changeset
3572 if (interrupted && clear_interrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3573 osthread->set_interrupted(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 // consider thread->_SleepEvent->reset() ... optional optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3576
a61af66fc99e Initial load
duke
parents:
diff changeset
3577 return interrupted;
a61af66fc99e Initial load
duke
parents:
diff changeset
3578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3579
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 ///////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 // signal handling (except suspend/resume)
a61af66fc99e Initial load
duke
parents:
diff changeset
3582
a61af66fc99e Initial load
duke
parents:
diff changeset
3583 // This routine may be used by user applications as a "hook" to catch signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 // The user-defined signal handler must pass unrecognized signals to this
a61af66fc99e Initial load
duke
parents:
diff changeset
3585 // routine, and if it returns true (non-zero), then the signal handler must
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 // return immediately. If the flag "abort_if_unrecognized" is true, then this
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 // routine will never retun false (zero), but instead will execute a VM panic
a61af66fc99e Initial load
duke
parents:
diff changeset
3588 // routine kill the process.
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 // If this routine returns false, it is OK to call it again. This allows
a61af66fc99e Initial load
duke
parents:
diff changeset
3591 // the user-defined signal handler to perform checks either before or after
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 // the VM performs its own checks. Naturally, the user code would be making
a61af66fc99e Initial load
duke
parents:
diff changeset
3593 // a serious error if it tried to handle an exception (such as a null check
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 // or breakpoint) that the VM was generating for its own correct operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 // This routine may recognize any of the following kinds of signals:
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 // SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1.
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 // It should be consulted by handlers for any of those signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 // The caller of this routine must pass in the three arguments supplied
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 // to the function referred to in the "sa_sigaction" (not the "sa_handler")
a61af66fc99e Initial load
duke
parents:
diff changeset
3602 // field of the structure passed to sigaction(). This routine assumes that
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 // the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 // Note that the VM will print warnings if it detects conflicting signal
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 //
2191
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
3608 extern "C" JNIEXPORT int
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 JVM_handle_linux_signal(int signo, siginfo_t* siginfo,
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 void* ucontext, int abort_if_unrecognized);
a61af66fc99e Initial load
duke
parents:
diff changeset
3611
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 void signalHandler(int sig, siginfo_t* info, void* uc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3613 assert(info != NULL && uc != NULL, "it must be old kernel");
1942
00bc9eaf0e24 Support for -XX:+UseFastLocking flag. Fixed monitor enter XIR template for correct debug info at the runtime call.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1936
diff changeset
3614 ResourceMark rm;
1936
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1867
diff changeset
3615 if (TraceSignals) {
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1867
diff changeset
3616 tty->print_cr(err_msg("signal received: code=%d errno=%d signo=%d thread=%s address=%x", info->si_code, info->si_errno, info->si_signo, Thread::current()->name(), info->si_addr));
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1867
diff changeset
3617 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 JVM_handle_linux_signal(sig, info, uc, true);
1936
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1867
diff changeset
3619 if (TraceSignals) {
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1867
diff changeset
3620 tty->print_cr("signal handled");
8d88c9ac9247 Correct deopt handler entry. New flag -XX:+TraceSignals. More detailed deopt printing.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents: 1867
diff changeset
3621 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3623
a61af66fc99e Initial load
duke
parents:
diff changeset
3624
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 // This boolean allows users to forward their own non-matching signals
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 // to JVM_handle_linux_signal, harmlessly.
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 bool os::Linux::signal_handlers_are_installed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3628
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 // For signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 struct sigaction os::Linux::sigact[MAXSIGNUM];
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 unsigned int os::Linux::sigs = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 bool os::Linux::libjsig_is_loaded = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 typedef struct sigaction *(*get_signal_t)(int);
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 get_signal_t os::Linux::get_signal_action = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3635
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 struct sigaction* os::Linux::get_chained_signal_action(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 struct sigaction *actp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3638
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 if (libjsig_is_loaded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 // Retrieve the old signal handler from libjsig
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 actp = (*get_signal_action)(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 if (actp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 // Retrieve the preinstalled signal handler from jvm
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 actp = get_preinstalled_handler(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3647
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 return actp;
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3650
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 static bool call_chained_handler(struct sigaction *actp, int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 siginfo_t *siginfo, void *context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 // Call the old signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 if (actp->sa_handler == SIG_DFL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 // It's more reasonable to let jvm treat it as an unexpected exception
a61af66fc99e Initial load
duke
parents:
diff changeset
3656 // instead of taking the default action.
a61af66fc99e Initial load
duke
parents:
diff changeset
3657 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 } else if (actp->sa_handler != SIG_IGN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 if ((actp->sa_flags & SA_NODEFER) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3660 // automaticlly block the signal
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 sigaddset(&(actp->sa_mask), sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3663
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 sa_handler_t hand;
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 sa_sigaction_t sa;
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 // retrieve the chained handler
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 if (siginfo_flag_set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 sa = actp->sa_sigaction;
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 hand = actp->sa_handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3673
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 if ((actp->sa_flags & SA_RESETHAND) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 actp->sa_handler = SIG_DFL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3677
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 // try to honor the signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 sigset_t oset;
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3681
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 // call into the chained handler
a61af66fc99e Initial load
duke
parents:
diff changeset
3683 if (siginfo_flag_set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 (*sa)(sig, siginfo, context);
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 (*hand)(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3688
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 // restore the signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
3690 pthread_sigmask(SIG_SETMASK, &oset, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 // Tell jvm's signal handler the signal is taken care of.
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3695
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 bool chained = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 // signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3700 struct sigaction *actp = get_chained_signal_action(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
3701 if (actp != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 chained = call_chained_handler(actp, sig, siginfo, context);
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 return chained;
a61af66fc99e Initial load
duke
parents:
diff changeset
3706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3707
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 struct sigaction* os::Linux::get_preinstalled_handler(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 if ((( (unsigned int)1 << sig ) & sigs) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 return &sigact[sig];
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3712 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3714
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
3717 sigact[sig] = oldAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
3718 sigs |= (unsigned int)1 << sig;
a61af66fc99e Initial load
duke
parents:
diff changeset
3719 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3720
a61af66fc99e Initial load
duke
parents:
diff changeset
3721 // for diagnostic
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 int os::Linux::sigflags[MAXSIGNUM];
a61af66fc99e Initial load
duke
parents:
diff changeset
3723
a61af66fc99e Initial load
duke
parents:
diff changeset
3724 int os::Linux::get_our_sigflags(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 return sigflags[sig];
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3728
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 void os::Linux::set_our_sigflags(int sig, int flags) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3730 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
3731 sigflags[sig] = flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3733
a61af66fc99e Initial load
duke
parents:
diff changeset
3734 void os::Linux::set_signal_handler(int sig, bool set_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 // Check for overwrite.
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 struct sigaction oldAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 sigaction(sig, (struct sigaction*)NULL, &oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
3738
a61af66fc99e Initial load
duke
parents:
diff changeset
3739 void* oldhand = oldAct.sa_sigaction
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
3742 if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3743 oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3744 oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 if (AllowUserSignalHandlers || !set_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3746 // Do not overwrite; user takes responsibility to forward to us.
a61af66fc99e Initial load
duke
parents:
diff changeset
3747 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3748 } else if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 // save the old handler in jvm
a61af66fc99e Initial load
duke
parents:
diff changeset
3750 save_preinstalled_handler(sig, oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 // libjsig also interposes the sigaction() call below and saves the
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 // old sigaction on it own.
a61af66fc99e Initial load
duke
parents:
diff changeset
3753 } else {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
3754 fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
3755 "%#lx for signal %d.", (long)oldhand, sig));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3758
a61af66fc99e Initial load
duke
parents:
diff changeset
3759 struct sigaction sigAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
3760 sigfillset(&(sigAct.sa_mask));
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 sigAct.sa_handler = SIG_DFL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 if (!set_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3765 sigAct.sa_sigaction = signalHandler;
a61af66fc99e Initial load
duke
parents:
diff changeset
3766 sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
a61af66fc99e Initial load
duke
parents:
diff changeset
3767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 // Save flags, which are set by ours
a61af66fc99e Initial load
duke
parents:
diff changeset
3769 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 sigflags[sig] = sigAct.sa_flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
3771
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 int ret = sigaction(sig, &sigAct, &oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
3773 assert(ret == 0, "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3774
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 void* oldhand2 = oldAct.sa_sigaction
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
3777 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
3778 assert(oldhand2 == oldhand, "no concurrent signal handler installation");
a61af66fc99e Initial load
duke
parents:
diff changeset
3779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3780
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 // install signal handlers for signals that HotSpot needs to
a61af66fc99e Initial load
duke
parents:
diff changeset
3782 // handle in order to support Java-level exception handling.
a61af66fc99e Initial load
duke
parents:
diff changeset
3783
a61af66fc99e Initial load
duke
parents:
diff changeset
3784 void os::Linux::install_signal_handlers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3785 if (!signal_handlers_are_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3786 signal_handlers_are_installed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3787
a61af66fc99e Initial load
duke
parents:
diff changeset
3788 // signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 typedef void (*signal_setting_t)();
a61af66fc99e Initial load
duke
parents:
diff changeset
3790 signal_setting_t begin_signal_setting = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 signal_setting_t end_signal_setting = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));
a61af66fc99e Initial load
duke
parents:
diff changeset
3794 if (begin_signal_setting != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3795 end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
3796 dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 get_signal_action = CAST_TO_FN_PTR(get_signal_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
a61af66fc99e Initial load
duke
parents:
diff changeset
3799 libjsig_is_loaded = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3800 assert(UseSignalChaining, "should enable signal-chaining");
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3802 if (libjsig_is_loaded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3803 // Tell libjsig jvm is setting signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
3804 (*begin_signal_setting)();
a61af66fc99e Initial load
duke
parents:
diff changeset
3805 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3806
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 set_signal_handler(SIGSEGV, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 set_signal_handler(SIGPIPE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3809 set_signal_handler(SIGBUS, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 set_signal_handler(SIGILL, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3811 set_signal_handler(SIGFPE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 set_signal_handler(SIGXFSZ, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3813
a61af66fc99e Initial load
duke
parents:
diff changeset
3814 if (libjsig_is_loaded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3815 // Tell libjsig jvm finishes setting signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 (*end_signal_setting)();
a61af66fc99e Initial load
duke
parents:
diff changeset
3817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3818
a61af66fc99e Initial load
duke
parents:
diff changeset
3819 // We don't activate signal checker if libjsig is in place, we trust ourselves
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 // and if UserSignalHandler is installed all bets are off
a61af66fc99e Initial load
duke
parents:
diff changeset
3821 if (CheckJNICalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3822 if (libjsig_is_loaded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 check_signals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3826 if (AllowUserSignalHandlers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3827 tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
3828 check_signals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3832 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3833
a61af66fc99e Initial load
duke
parents:
diff changeset
3834 // This is the fastest way to get thread cpu time on Linux.
a61af66fc99e Initial load
duke
parents:
diff changeset
3835 // Returns cpu time (user+sys) for any thread, not only for current.
a61af66fc99e Initial load
duke
parents:
diff changeset
3836 // POSIX compliant clocks are implemented in the kernels 2.6.16+.
a61af66fc99e Initial load
duke
parents:
diff changeset
3837 // It might work on 2.6.10+ with a special kernel/glibc patch.
a61af66fc99e Initial load
duke
parents:
diff changeset
3838 // For reference, please, see IEEE Std 1003.1-2004:
a61af66fc99e Initial load
duke
parents:
diff changeset
3839 // http://www.unix.org/single_unix_specification
a61af66fc99e Initial load
duke
parents:
diff changeset
3840
a61af66fc99e Initial load
duke
parents:
diff changeset
3841 jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3842 struct timespec tp;
a61af66fc99e Initial load
duke
parents:
diff changeset
3843 int rc = os::Linux::clock_gettime(clockid, &tp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3844 assert(rc == 0, "clock_gettime is expected to return 0 code");
a61af66fc99e Initial load
duke
parents:
diff changeset
3845
a61af66fc99e Initial load
duke
parents:
diff changeset
3846 return (tp.tv_sec * SEC_IN_NANOSECS) + tp.tv_nsec;
a61af66fc99e Initial load
duke
parents:
diff changeset
3847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3848
a61af66fc99e Initial load
duke
parents:
diff changeset
3849 /////
a61af66fc99e Initial load
duke
parents:
diff changeset
3850 // glibc on Linux platform uses non-documented flag
a61af66fc99e Initial load
duke
parents:
diff changeset
3851 // to indicate, that some special sort of signal
a61af66fc99e Initial load
duke
parents:
diff changeset
3852 // trampoline is used.
a61af66fc99e Initial load
duke
parents:
diff changeset
3853 // We will never set this flag, and we should
a61af66fc99e Initial load
duke
parents:
diff changeset
3854 // ignore this flag in our diagnostic
a61af66fc99e Initial load
duke
parents:
diff changeset
3855 #ifdef SIGNIFICANT_SIGNAL_MASK
a61af66fc99e Initial load
duke
parents:
diff changeset
3856 #undef SIGNIFICANT_SIGNAL_MASK
a61af66fc99e Initial load
duke
parents:
diff changeset
3857 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 #define SIGNIFICANT_SIGNAL_MASK (~0x04000000)
a61af66fc99e Initial load
duke
parents:
diff changeset
3859
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 static const char* get_signal_handler_name(address handler,
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 char* buf, int buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3862 int offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
3863 bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 if (found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3865 // skip directory names
a61af66fc99e Initial load
duke
parents:
diff changeset
3866 const char *p1, *p2;
a61af66fc99e Initial load
duke
parents:
diff changeset
3867 p1 = buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
3868 size_t len = strlen(os::file_separator());
a61af66fc99e Initial load
duke
parents:
diff changeset
3869 while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
a61af66fc99e Initial load
duke
parents:
diff changeset
3870 jio_snprintf(buf, buflen, "%s+0x%x", p1, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
3871 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 jio_snprintf(buf, buflen, PTR_FORMAT, handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
3873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3874 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
3875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3876
a61af66fc99e Initial load
duke
parents:
diff changeset
3877 static void print_signal_handler(outputStream* st, int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
3878 char* buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3879 struct sigaction sa;
a61af66fc99e Initial load
duke
parents:
diff changeset
3880
a61af66fc99e Initial load
duke
parents:
diff changeset
3881 sigaction(sig, NULL, &sa);
a61af66fc99e Initial load
duke
parents:
diff changeset
3882
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 // See comment for SIGNIFICANT_SIGNAL_MASK define
a61af66fc99e Initial load
duke
parents:
diff changeset
3884 sa.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3885
a61af66fc99e Initial load
duke
parents:
diff changeset
3886 st->print("%s: ", os::exception_name(sig, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
3887
a61af66fc99e Initial load
duke
parents:
diff changeset
3888 address handler = (sa.sa_flags & SA_SIGINFO)
a61af66fc99e Initial load
duke
parents:
diff changeset
3889 ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
3890 : CAST_FROM_FN_PTR(address, sa.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
3891
a61af66fc99e Initial load
duke
parents:
diff changeset
3892 if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3893 st->print("SIG_DFL");
a61af66fc99e Initial load
duke
parents:
diff changeset
3894 } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3895 st->print("SIG_IGN");
a61af66fc99e Initial load
duke
parents:
diff changeset
3896 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3897 st->print("[%s]", get_signal_handler_name(handler, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
3898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3899
a61af66fc99e Initial load
duke
parents:
diff changeset
3900 st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
3901
a61af66fc99e Initial load
duke
parents:
diff changeset
3902 address rh = VMError::get_resetted_sighandler(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
3903 // May be, handler was resetted by VMError?
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 if(rh != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3905 handler = rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
3906 sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3907 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3908
a61af66fc99e Initial load
duke
parents:
diff changeset
3909 st->print(", sa_flags=" PTR32_FORMAT, sa.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
3910
a61af66fc99e Initial load
duke
parents:
diff changeset
3911 // Check: is it our handler?
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3913 handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3914 // It is our signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 // check for flags, reset system-used one!
a61af66fc99e Initial load
duke
parents:
diff changeset
3916 if((int)sa.sa_flags != os::Linux::get_our_sigflags(sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3917 st->print(
a61af66fc99e Initial load
duke
parents:
diff changeset
3918 ", flags was changed from " PTR32_FORMAT ", consider using jsig library",
a61af66fc99e Initial load
duke
parents:
diff changeset
3919 os::Linux::get_our_sigflags(sig));
a61af66fc99e Initial load
duke
parents:
diff changeset
3920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3922 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3924
a61af66fc99e Initial load
duke
parents:
diff changeset
3925
a61af66fc99e Initial load
duke
parents:
diff changeset
3926 #define DO_SIGNAL_CHECK(sig) \
a61af66fc99e Initial load
duke
parents:
diff changeset
3927 if (!sigismember(&check_signal_done, sig)) \
a61af66fc99e Initial load
duke
parents:
diff changeset
3928 os::Linux::check_signal_handler(sig)
a61af66fc99e Initial load
duke
parents:
diff changeset
3929
a61af66fc99e Initial load
duke
parents:
diff changeset
3930 // This method is a periodic task to check for misbehaving JNI applications
a61af66fc99e Initial load
duke
parents:
diff changeset
3931 // under CheckJNI, we can add any periodic checks here
a61af66fc99e Initial load
duke
parents:
diff changeset
3932
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 void os::run_periodic_checks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3934
a61af66fc99e Initial load
duke
parents:
diff changeset
3935 if (check_signals == false) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3936
a61af66fc99e Initial load
duke
parents:
diff changeset
3937 // SEGV and BUS if overridden could potentially prevent
a61af66fc99e Initial load
duke
parents:
diff changeset
3938 // generation of hs*.log in the event of a crash, debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
3939 // such a case can be very challenging, so we absolutely
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 // check the following for a good measure:
a61af66fc99e Initial load
duke
parents:
diff changeset
3941 DO_SIGNAL_CHECK(SIGSEGV);
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 DO_SIGNAL_CHECK(SIGILL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3943 DO_SIGNAL_CHECK(SIGFPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3944 DO_SIGNAL_CHECK(SIGBUS);
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 DO_SIGNAL_CHECK(SIGPIPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3946 DO_SIGNAL_CHECK(SIGXFSZ);
a61af66fc99e Initial load
duke
parents:
diff changeset
3947
a61af66fc99e Initial load
duke
parents:
diff changeset
3948
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 // ReduceSignalUsage allows the user to override these handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 // see comments at the very top and jvm_solaris.h
a61af66fc99e Initial load
duke
parents:
diff changeset
3951 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3953 DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3954 DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3955 DO_SIGNAL_CHECK(BREAK_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3956 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3957
a61af66fc99e Initial load
duke
parents:
diff changeset
3958 DO_SIGNAL_CHECK(SR_signum);
a61af66fc99e Initial load
duke
parents:
diff changeset
3959 DO_SIGNAL_CHECK(INTERRUPT_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3961
a61af66fc99e Initial load
duke
parents:
diff changeset
3962 typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
a61af66fc99e Initial load
duke
parents:
diff changeset
3963
a61af66fc99e Initial load
duke
parents:
diff changeset
3964 static os_sigaction_t os_sigaction = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3965
a61af66fc99e Initial load
duke
parents:
diff changeset
3966 void os::Linux::check_signal_handler(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 char buf[O_BUFLEN];
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 address jvmHandler = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3969
a61af66fc99e Initial load
duke
parents:
diff changeset
3970
a61af66fc99e Initial load
duke
parents:
diff changeset
3971 struct sigaction act;
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 if (os_sigaction == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3973 // only trust the default sigaction, in case it has been interposed
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");
a61af66fc99e Initial load
duke
parents:
diff changeset
3975 if (os_sigaction == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3977
a61af66fc99e Initial load
duke
parents:
diff changeset
3978 os_sigaction(sig, (struct sigaction*)NULL, &act);
a61af66fc99e Initial load
duke
parents:
diff changeset
3979
a61af66fc99e Initial load
duke
parents:
diff changeset
3980
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 act.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3982
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 address thisHandler = (act.sa_flags & SA_SIGINFO)
a61af66fc99e Initial load
duke
parents:
diff changeset
3984 ? CAST_FROM_FN_PTR(address, act.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
3985 : CAST_FROM_FN_PTR(address, act.sa_handler) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3986
a61af66fc99e Initial load
duke
parents:
diff changeset
3987
a61af66fc99e Initial load
duke
parents:
diff changeset
3988 switch(sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3989 case SIGSEGV:
a61af66fc99e Initial load
duke
parents:
diff changeset
3990 case SIGBUS:
a61af66fc99e Initial load
duke
parents:
diff changeset
3991 case SIGFPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 case SIGPIPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
3993 case SIGILL:
a61af66fc99e Initial load
duke
parents:
diff changeset
3994 case SIGXFSZ:
a61af66fc99e Initial load
duke
parents:
diff changeset
3995 jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
3996 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3997
a61af66fc99e Initial load
duke
parents:
diff changeset
3998 case SHUTDOWN1_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 case SHUTDOWN2_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4000 case SHUTDOWN3_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4001 case BREAK_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4002 jvmHandler = (address)user_handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4004
a61af66fc99e Initial load
duke
parents:
diff changeset
4005 case INTERRUPT_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4006 jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4007 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4008
a61af66fc99e Initial load
duke
parents:
diff changeset
4009 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
4010 if (sig == SR_signum) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4011 jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4012 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4015 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4017
a61af66fc99e Initial load
duke
parents:
diff changeset
4018 if (thisHandler != jvmHandler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4019 tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4020 tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4021 tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4022 // No need to check this sig any longer
a61af66fc99e Initial load
duke
parents:
diff changeset
4023 sigaddset(&check_signal_done, sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4024 } else if(os::Linux::get_our_sigflags(sig) != 0 && (int)act.sa_flags != os::Linux::get_our_sigflags(sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4025 tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4026 tty->print("expected:" PTR32_FORMAT, os::Linux::get_our_sigflags(sig));
a61af66fc99e Initial load
duke
parents:
diff changeset
4027 tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
4028 // No need to check this sig any longer
a61af66fc99e Initial load
duke
parents:
diff changeset
4029 sigaddset(&check_signal_done, sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4031
a61af66fc99e Initial load
duke
parents:
diff changeset
4032 // Dump all the signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4033 if (sigismember(&check_signal_done, sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4034 print_signal_handlers(tty, buf, O_BUFLEN);
a61af66fc99e Initial load
duke
parents:
diff changeset
4035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4037
a61af66fc99e Initial load
duke
parents:
diff changeset
4038 extern void report_error(char* file_name, int line_no, char* title, char* format, ...);
a61af66fc99e Initial load
duke
parents:
diff changeset
4039
a61af66fc99e Initial load
duke
parents:
diff changeset
4040 extern bool signal_name(int signo, char* buf, size_t len);
a61af66fc99e Initial load
duke
parents:
diff changeset
4041
a61af66fc99e Initial load
duke
parents:
diff changeset
4042 const char* os::exception_name(int exception_code, char* buf, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 if (0 < exception_code && exception_code <= SIGRTMAX) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4044 // signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4045 if (!signal_name(exception_code, buf, size)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4046 jio_snprintf(buf, size, "SIG%d", exception_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
4047 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4048 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
4049 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4050 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4053
a61af66fc99e Initial load
duke
parents:
diff changeset
4054 // this is called _before_ the most of global arguments have been parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
4055 void os::init(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4056 char dummy; /* used to get a guess on initial stack address */
a61af66fc99e Initial load
duke
parents:
diff changeset
4057 // first_hrtime = gethrtime();
a61af66fc99e Initial load
duke
parents:
diff changeset
4058
a61af66fc99e Initial load
duke
parents:
diff changeset
4059 // With LinuxThreads the JavaMain thread pid (primordial thread)
a61af66fc99e Initial load
duke
parents:
diff changeset
4060 // is different than the pid of the java launcher thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
4061 // So, on Linux, the launcher thread pid is passed to the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
4062 // via the sun.java.launcher.pid property.
a61af66fc99e Initial load
duke
parents:
diff changeset
4063 // Use this property instead of getpid() if it was correctly passed.
a61af66fc99e Initial load
duke
parents:
diff changeset
4064 // See bug 6351349.
a61af66fc99e Initial load
duke
parents:
diff changeset
4065 pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid();
a61af66fc99e Initial load
duke
parents:
diff changeset
4066
a61af66fc99e Initial load
duke
parents:
diff changeset
4067 _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid();
a61af66fc99e Initial load
duke
parents:
diff changeset
4068
a61af66fc99e Initial load
duke
parents:
diff changeset
4069 clock_tics_per_sec = sysconf(_SC_CLK_TCK);
a61af66fc99e Initial load
duke
parents:
diff changeset
4070
a61af66fc99e Initial load
duke
parents:
diff changeset
4071 init_random(1234567);
a61af66fc99e Initial load
duke
parents:
diff changeset
4072
a61af66fc99e Initial load
duke
parents:
diff changeset
4073 ThreadCritical::initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
4074
a61af66fc99e Initial load
duke
parents:
diff changeset
4075 Linux::set_page_size(sysconf(_SC_PAGESIZE));
a61af66fc99e Initial load
duke
parents:
diff changeset
4076 if (Linux::page_size() == -1) {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4077 fatal(err_msg("os_linux.cpp: os::init: sysconf failed (%s)",
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4078 strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4080 init_page_sizes((size_t) Linux::page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
4081
a61af66fc99e Initial load
duke
parents:
diff changeset
4082 Linux::initialize_system_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
4083
a61af66fc99e Initial load
duke
parents:
diff changeset
4084 // main_thread points to the aboriginal thread
a61af66fc99e Initial load
duke
parents:
diff changeset
4085 Linux::_main_thread = pthread_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
4086
a61af66fc99e Initial load
duke
parents:
diff changeset
4087 Linux::clock_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4088 initial_time_count = os::elapsed_counter();
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
4089 pthread_mutex_init(&dl_mutex, NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4091
a61af66fc99e Initial load
duke
parents:
diff changeset
4092 // To install functions for atexit system call
a61af66fc99e Initial load
duke
parents:
diff changeset
4093 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 static void perfMemory_exit_helper() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4095 perfMemory_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4097 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4098
a61af66fc99e Initial load
duke
parents:
diff changeset
4099 // this is called _after_ the global arguments have been parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
4100 jint os::init_2(void)
a61af66fc99e Initial load
duke
parents:
diff changeset
4101 {
a61af66fc99e Initial load
duke
parents:
diff changeset
4102 Linux::fast_thread_clock_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4103
a61af66fc99e Initial load
duke
parents:
diff changeset
4104 // Allocate a single page and mark it as readable for safepoint polling
a61af66fc99e Initial load
duke
parents:
diff changeset
4105 address polling_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4106 guarantee( polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page" );
a61af66fc99e Initial load
duke
parents:
diff changeset
4107
a61af66fc99e Initial load
duke
parents:
diff changeset
4108 os::set_polling_page( polling_page );
a61af66fc99e Initial load
duke
parents:
diff changeset
4109
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
4111 if(Verbose && PrintMiscellaneous)
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
a61af66fc99e Initial load
duke
parents:
diff changeset
4113 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4114
a61af66fc99e Initial load
duke
parents:
diff changeset
4115 if (!UseMembar) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4116 address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4117 guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page");
a61af66fc99e Initial load
duke
parents:
diff changeset
4118 os::set_memory_serialize_page( mem_serialize_page );
a61af66fc99e Initial load
duke
parents:
diff changeset
4119
a61af66fc99e Initial load
duke
parents:
diff changeset
4120 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
4121 if(Verbose && PrintMiscellaneous)
a61af66fc99e Initial load
duke
parents:
diff changeset
4122 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
a61af66fc99e Initial load
duke
parents:
diff changeset
4123 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4125
3318
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
4126 os::large_page_init();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4127
a61af66fc99e Initial load
duke
parents:
diff changeset
4128 // initialize suspend/resume support - must do this before signal_sets_init()
a61af66fc99e Initial load
duke
parents:
diff changeset
4129 if (SR_initialize() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4130 perror("SR_initialize failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
4131 return JNI_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
4132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4133
a61af66fc99e Initial load
duke
parents:
diff changeset
4134 Linux::signal_sets_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4135 Linux::install_signal_handlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
4136
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4137 // Check minimum allowable stack size for thread creation and to initialize
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4138 // the java system classes, including StackOverflowError - depends on page
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4139 // size. Add a page for compiler2 recursion in main thread.
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4140 // Add in 2*BytesPerWord times page size to account for VM stack during
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4141 // class initialization depending on 32 or 64 bit VM.
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4142 os::Linux::min_stack_allowed = MAX2(os::Linux::min_stack_allowed,
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4143 (size_t)(StackYellowPages+StackRedPages+StackShadowPages+
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4144 2*BytesPerWord COMPILER2_PRESENT(+1)) * Linux::page_size());
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4145
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4146 size_t threadStackSizeInBytes = ThreadStackSize * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
4147 if (threadStackSizeInBytes != 0 &&
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4148 threadStackSizeInBytes < os::Linux::min_stack_allowed) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4149 tty->print_cr("\nThe stack size specified is too small, "
a61af66fc99e Initial load
duke
parents:
diff changeset
4150 "Specify at least %dk",
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4151 os::Linux::min_stack_allowed/ K);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4152 return JNI_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
4153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4154
a61af66fc99e Initial load
duke
parents:
diff changeset
4155 // Make the stack size a multiple of the page size so that
a61af66fc99e Initial load
duke
parents:
diff changeset
4156 // the yellow/red zones can be guarded.
a61af66fc99e Initial load
duke
parents:
diff changeset
4157 JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
4158 vm_page_size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
4159
a61af66fc99e Initial load
duke
parents:
diff changeset
4160 Linux::capture_initial_stack(JavaThread::stack_size_at_create());
a61af66fc99e Initial load
duke
parents:
diff changeset
4161
a61af66fc99e Initial load
duke
parents:
diff changeset
4162 Linux::libpthread_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4163 if (PrintMiscellaneous && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4164 tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4165 Linux::glibc_version(), Linux::libpthread_version(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4166 Linux::is_floating_stack() ? "floating stack" : "fixed stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
4167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4168
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
4169 if (UseNUMA) {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4170 if (!Linux::libnuma_init()) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4171 UseNUMA = false;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4172 } else {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4173 if ((Linux::numa_max_node() < 1)) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4174 // There's only one node(they start from 0), disable NUMA.
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4175 UseNUMA = false;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4176 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4177 }
3292
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4178 // With SHM large pages we cannot uncommit a page, so there's not way
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4179 // we can make the adaptive lgrp chunk resizing work. If the user specified
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4180 // both UseNUMA and UseLargePages (or UseSHM) on the command line - warn and
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4181 // disable adaptive resizing.
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4182 if (UseNUMA && UseLargePages && UseSHM) {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4183 if (!FLAG_IS_DEFAULT(UseNUMA)) {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4184 if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseSHM)) {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4185 UseLargePages = false;
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4186 } else {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4187 warning("UseNUMA is not fully compatible with SHM large pages, disabling adaptive resizing");
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4188 UseAdaptiveSizePolicy = false;
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4189 UseAdaptiveNUMAChunkSizing = false;
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4190 }
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4191 } else {
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4192 UseNUMA = false;
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4193 }
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4194 }
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4195 if (!UseNUMA && ForceNUMA) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4196 UseNUMA = true;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4197 }
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
4198 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
4199
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4200 if (MaxFDLimit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4201 // set the number of file descriptors to max. print out error
a61af66fc99e Initial load
duke
parents:
diff changeset
4202 // if getrlimit/setrlimit fails but continue regardless.
a61af66fc99e Initial load
duke
parents:
diff changeset
4203 struct rlimit nbr_files;
a61af66fc99e Initial load
duke
parents:
diff changeset
4204 int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
a61af66fc99e Initial load
duke
parents:
diff changeset
4205 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4206 if (PrintMiscellaneous && (Verbose || WizardMode))
a61af66fc99e Initial load
duke
parents:
diff changeset
4207 perror("os::init_2 getrlimit failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
4208 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4209 nbr_files.rlim_cur = nbr_files.rlim_max;
a61af66fc99e Initial load
duke
parents:
diff changeset
4210 status = setrlimit(RLIMIT_NOFILE, &nbr_files);
a61af66fc99e Initial load
duke
parents:
diff changeset
4211 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4212 if (PrintMiscellaneous && (Verbose || WizardMode))
a61af66fc99e Initial load
duke
parents:
diff changeset
4213 perror("os::init_2 setrlimit failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
4214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4217
a61af66fc99e Initial load
duke
parents:
diff changeset
4218 // Initialize lock used to serialize thread creation (see os::create_thread)
a61af66fc99e Initial load
duke
parents:
diff changeset
4219 Linux::set_createThread_lock(new Mutex(Mutex::leaf, "createThread_lock", false));
a61af66fc99e Initial load
duke
parents:
diff changeset
4220
a61af66fc99e Initial load
duke
parents:
diff changeset
4221 // at-exit methods are called in the reverse order of their registration.
a61af66fc99e Initial load
duke
parents:
diff changeset
4222 // atexit functions are called on return from main or as a result of a
a61af66fc99e Initial load
duke
parents:
diff changeset
4223 // call to exit(3C). There can be only 32 of these functions registered
a61af66fc99e Initial load
duke
parents:
diff changeset
4224 // and atexit() does not set errno.
a61af66fc99e Initial load
duke
parents:
diff changeset
4225
a61af66fc99e Initial load
duke
parents:
diff changeset
4226 if (PerfAllowAtExitRegistration) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4227 // only register atexit functions if PerfAllowAtExitRegistration is set.
a61af66fc99e Initial load
duke
parents:
diff changeset
4228 // atexit functions can be delayed until process exit time, which
a61af66fc99e Initial load
duke
parents:
diff changeset
4229 // can be problematic for embedded VM situations. Embedded VMs should
a61af66fc99e Initial load
duke
parents:
diff changeset
4230 // call DestroyJavaVM() to assure that VM resources are released.
a61af66fc99e Initial load
duke
parents:
diff changeset
4231
a61af66fc99e Initial load
duke
parents:
diff changeset
4232 // note: perfMemory_exit_helper atexit function may be removed in
a61af66fc99e Initial load
duke
parents:
diff changeset
4233 // the future if the appropriate cleanup code can be added to the
a61af66fc99e Initial load
duke
parents:
diff changeset
4234 // VM_Exit VMOperation's doit method.
a61af66fc99e Initial load
duke
parents:
diff changeset
4235 if (atexit(perfMemory_exit_helper) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4236 warning("os::init2 atexit(perfMemory_exit_helper) failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
4237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4239
a61af66fc99e Initial load
duke
parents:
diff changeset
4240 // initialize thread priority policy
a61af66fc99e Initial load
duke
parents:
diff changeset
4241 prio_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4242
a61af66fc99e Initial load
duke
parents:
diff changeset
4243 return JNI_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4245
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4246 // this is called at the end of vm_initialization
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4247 void os::init_3(void) { }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4248
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4249 // Mark the polling page as unreadable
a61af66fc99e Initial load
duke
parents:
diff changeset
4250 void os::make_polling_page_unreadable(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4251 if( !guard_memory((char*)_polling_page, Linux::page_size()) )
a61af66fc99e Initial load
duke
parents:
diff changeset
4252 fatal("Could not disable polling page");
a61af66fc99e Initial load
duke
parents:
diff changeset
4253 };
a61af66fc99e Initial load
duke
parents:
diff changeset
4254
a61af66fc99e Initial load
duke
parents:
diff changeset
4255 // Mark the polling page as readable
a61af66fc99e Initial load
duke
parents:
diff changeset
4256 void os::make_polling_page_readable(void) {
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
4257 if( !linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4258 fatal("Could not enable polling page");
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
4259 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4260 };
a61af66fc99e Initial load
duke
parents:
diff changeset
4261
a61af66fc99e Initial load
duke
parents:
diff changeset
4262 int os::active_processor_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4263 // Linux doesn't yet have a (official) notion of processor sets,
a61af66fc99e Initial load
duke
parents:
diff changeset
4264 // so just return the number of online processors.
a61af66fc99e Initial load
duke
parents:
diff changeset
4265 int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
a61af66fc99e Initial load
duke
parents:
diff changeset
4266 assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
4267 return online_cpus;
a61af66fc99e Initial load
duke
parents:
diff changeset
4268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4269
a61af66fc99e Initial load
duke
parents:
diff changeset
4270 bool os::distribute_processes(uint length, uint* distribution) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4271 // Not yet implemented.
a61af66fc99e Initial load
duke
parents:
diff changeset
4272 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4274
a61af66fc99e Initial load
duke
parents:
diff changeset
4275 bool os::bind_to_processor(uint processor_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4276 // Not yet implemented.
a61af66fc99e Initial load
duke
parents:
diff changeset
4277 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4279
a61af66fc99e Initial load
duke
parents:
diff changeset
4280 ///
a61af66fc99e Initial load
duke
parents:
diff changeset
4281
a61af66fc99e Initial load
duke
parents:
diff changeset
4282 // Suspends the target using the signal mechanism and then grabs the PC before
a61af66fc99e Initial load
duke
parents:
diff changeset
4283 // resuming the target. Used by the flat-profiler only
a61af66fc99e Initial load
duke
parents:
diff changeset
4284 ExtendedPC os::get_thread_pc(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4285 // Make sure that it is called by the watcher for the VMThread
a61af66fc99e Initial load
duke
parents:
diff changeset
4286 assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
a61af66fc99e Initial load
duke
parents:
diff changeset
4287 assert(thread->is_VM_thread(), "Can only be called for VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
4288
a61af66fc99e Initial load
duke
parents:
diff changeset
4289 ExtendedPC epc;
a61af66fc99e Initial load
duke
parents:
diff changeset
4290
a61af66fc99e Initial load
duke
parents:
diff changeset
4291 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4292 if (do_suspend(osthread)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4293 if (osthread->ucontext() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4294 epc = os::Linux::ucontext_get_pc(osthread->ucontext());
a61af66fc99e Initial load
duke
parents:
diff changeset
4295 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4296 // NULL context is unexpected, double-check this is the VMThread
a61af66fc99e Initial load
duke
parents:
diff changeset
4297 guarantee(thread->is_VM_thread(), "can only be called for VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
4298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4299 do_resume(osthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
4300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4301 // failure means pthread_kill failed for some reason - arguably this is
a61af66fc99e Initial load
duke
parents:
diff changeset
4302 // a fatal problem, but such problems are ignored elsewhere
a61af66fc99e Initial load
duke
parents:
diff changeset
4303
a61af66fc99e Initial load
duke
parents:
diff changeset
4304 return epc;
a61af66fc99e Initial load
duke
parents:
diff changeset
4305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4306
a61af66fc99e Initial load
duke
parents:
diff changeset
4307 int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime)
a61af66fc99e Initial load
duke
parents:
diff changeset
4308 {
a61af66fc99e Initial load
duke
parents:
diff changeset
4309 if (is_NPTL()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4310 return pthread_cond_timedwait(_cond, _mutex, _abstime);
a61af66fc99e Initial load
duke
parents:
diff changeset
4311 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4312 #ifndef IA64
a61af66fc99e Initial load
duke
parents:
diff changeset
4313 // 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control
a61af66fc99e Initial load
duke
parents:
diff changeset
4314 // word back to default 64bit precision if condvar is signaled. Java
a61af66fc99e Initial load
duke
parents:
diff changeset
4315 // wants 53bit precision. Save and restore current value.
a61af66fc99e Initial load
duke
parents:
diff changeset
4316 int fpu = get_fpu_control_word();
a61af66fc99e Initial load
duke
parents:
diff changeset
4317 #endif // IA64
a61af66fc99e Initial load
duke
parents:
diff changeset
4318 int status = pthread_cond_timedwait(_cond, _mutex, _abstime);
a61af66fc99e Initial load
duke
parents:
diff changeset
4319 #ifndef IA64
a61af66fc99e Initial load
duke
parents:
diff changeset
4320 set_fpu_control_word(fpu);
a61af66fc99e Initial load
duke
parents:
diff changeset
4321 #endif // IA64
a61af66fc99e Initial load
duke
parents:
diff changeset
4322 return status;
a61af66fc99e Initial load
duke
parents:
diff changeset
4323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4325
a61af66fc99e Initial load
duke
parents:
diff changeset
4326 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
4327 // debug support
a61af66fc99e Initial load
duke
parents:
diff changeset
4328
a61af66fc99e Initial load
duke
parents:
diff changeset
4329 static address same_page(address x, address y) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4330 int page_bits = -os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
4331 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
a61af66fc99e Initial load
duke
parents:
diff changeset
4332 return x;
a61af66fc99e Initial load
duke
parents:
diff changeset
4333 else if (x > y)
a61af66fc99e Initial load
duke
parents:
diff changeset
4334 return (address)(intptr_t(y) | ~page_bits) + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4335 else
a61af66fc99e Initial load
duke
parents:
diff changeset
4336 return (address)(intptr_t(y) & page_bits);
a61af66fc99e Initial load
duke
parents:
diff changeset
4337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4338
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4339 bool os::find(address addr, outputStream* st) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4340 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
4341 memset(&dlinfo, 0, sizeof(dlinfo));
a61af66fc99e Initial load
duke
parents:
diff changeset
4342 if (dladdr(addr, &dlinfo)) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4343 st->print(PTR_FORMAT ": ", addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4344 if (dlinfo.dli_sname != NULL) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4345 st->print("%s+%#x", dlinfo.dli_sname,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4346 addr - (intptr_t)dlinfo.dli_saddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4347 } else if (dlinfo.dli_fname) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4348 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4349 } else {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4350 st->print("<absolute address>");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4352 if (dlinfo.dli_fname) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4353 st->print(" in %s", dlinfo.dli_fname);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4355 if (dlinfo.dli_fbase) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4356 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4357 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4358 st->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4359
a61af66fc99e Initial load
duke
parents:
diff changeset
4360 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4361 // decode some bytes around the PC
a61af66fc99e Initial load
duke
parents:
diff changeset
4362 address begin = same_page(addr-40, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4363 address end = same_page(addr+40, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4364 address lowest = (address) dlinfo.dli_sname;
a61af66fc99e Initial load
duke
parents:
diff changeset
4365 if (!lowest) lowest = (address) dlinfo.dli_fbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
4366 if (begin < lowest) begin = lowest;
a61af66fc99e Initial load
duke
parents:
diff changeset
4367 Dl_info dlinfo2;
a61af66fc99e Initial load
duke
parents:
diff changeset
4368 if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
a61af66fc99e Initial load
duke
parents:
diff changeset
4369 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
a61af66fc99e Initial load
duke
parents:
diff changeset
4370 end = (address) dlinfo2.dli_saddr;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4371 Disassembler::decode(begin, end, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4373 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4375 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4376 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4377
a61af66fc99e Initial load
duke
parents:
diff changeset
4378 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
4379 // misc
a61af66fc99e Initial load
duke
parents:
diff changeset
4380
a61af66fc99e Initial load
duke
parents:
diff changeset
4381 // This does not do anything on Linux. This is basically a hook for being
a61af66fc99e Initial load
duke
parents:
diff changeset
4382 // able to use structured exception handling (thread-local exception filters)
a61af66fc99e Initial load
duke
parents:
diff changeset
4383 // on, e.g., Win32.
a61af66fc99e Initial load
duke
parents:
diff changeset
4384 void
a61af66fc99e Initial load
duke
parents:
diff changeset
4385 os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method,
a61af66fc99e Initial load
duke
parents:
diff changeset
4386 JavaCallArguments* args, Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4387 f(value, method, args, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
4388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4389
a61af66fc99e Initial load
duke
parents:
diff changeset
4390 void os::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4392
a61af66fc99e Initial load
duke
parents:
diff changeset
4393 int os::message_box(const char* title, const char* message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4394 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
4395 fdStream err(defaultStream::error_fd());
a61af66fc99e Initial load
duke
parents:
diff changeset
4396 for (i = 0; i < 78; i++) err.print_raw("=");
a61af66fc99e Initial load
duke
parents:
diff changeset
4397 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4398 err.print_raw_cr(title);
a61af66fc99e Initial load
duke
parents:
diff changeset
4399 for (i = 0; i < 78; i++) err.print_raw("-");
a61af66fc99e Initial load
duke
parents:
diff changeset
4400 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4401 err.print_raw_cr(message);
a61af66fc99e Initial load
duke
parents:
diff changeset
4402 for (i = 0; i < 78; i++) err.print_raw("=");
a61af66fc99e Initial load
duke
parents:
diff changeset
4403 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4404
a61af66fc99e Initial load
duke
parents:
diff changeset
4405 char buf[16];
a61af66fc99e Initial load
duke
parents:
diff changeset
4406 // Prevent process from exiting upon "read error" without consuming all CPU
a61af66fc99e Initial load
duke
parents:
diff changeset
4407 while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }
a61af66fc99e Initial load
duke
parents:
diff changeset
4408
a61af66fc99e Initial load
duke
parents:
diff changeset
4409 return buf[0] == 'y' || buf[0] == 'Y';
a61af66fc99e Initial load
duke
parents:
diff changeset
4410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4411
a61af66fc99e Initial load
duke
parents:
diff changeset
4412 int os::stat(const char *path, struct stat *sbuf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4413 char pathbuf[MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
4414 if (strlen(path) > MAX_PATH - 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4415 errno = ENAMETOOLONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
4416 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4417 }
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4418 os::native_path(strcpy(pathbuf, path));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4419 return ::stat(pathbuf, sbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
4420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4421
a61af66fc99e Initial load
duke
parents:
diff changeset
4422 bool os::check_heap(bool force) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4423 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4425
a61af66fc99e Initial load
duke
parents:
diff changeset
4426 int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4427 return ::vsnprintf(buf, count, format, args);
a61af66fc99e Initial load
duke
parents:
diff changeset
4428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4429
a61af66fc99e Initial load
duke
parents:
diff changeset
4430 // Is a (classpath) directory empty?
a61af66fc99e Initial load
duke
parents:
diff changeset
4431 bool os::dir_is_empty(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4432 DIR *dir = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4433 struct dirent *ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4434
a61af66fc99e Initial load
duke
parents:
diff changeset
4435 dir = opendir(path);
a61af66fc99e Initial load
duke
parents:
diff changeset
4436 if (dir == NULL) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4437
a61af66fc99e Initial load
duke
parents:
diff changeset
4438 /* Scan the directory */
a61af66fc99e Initial load
duke
parents:
diff changeset
4439 bool result = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4440 char buf[sizeof(struct dirent) + MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
4441 while (result && (ptr = ::readdir(dir)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4442 if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4443 result = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4446 closedir(dir);
a61af66fc99e Initial load
duke
parents:
diff changeset
4447 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
4448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4449
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4450 // This code originates from JDK's sysOpen and open64_w
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4451 // from src/solaris/hpi/src/system_md.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4452
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4453 #ifndef O_DELETE
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4454 #define O_DELETE 0x10000
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4455 #endif
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4456
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4457 // Open a file. Unlink the file immediately after open returns
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4458 // if the specified oflag has the O_DELETE flag set.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4459 // O_DELETE is used only in j2se/src/share/native/java/util/zip/ZipFile.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4460
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4461 int os::open(const char *path, int oflag, int mode) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4462
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4463 if (strlen(path) > MAX_PATH - 1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4464 errno = ENAMETOOLONG;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4465 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4466 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4467 int fd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4468 int o_delete = (oflag & O_DELETE);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4469 oflag = oflag & ~O_DELETE;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4470
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4471 fd = ::open64(path, oflag, mode);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4472 if (fd == -1) return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4473
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4474 //If the open succeeded, the file might still be a directory
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4475 {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4476 struct stat64 buf64;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4477 int ret = ::fstat64(fd, &buf64);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4478 int st_mode = buf64.st_mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4479
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4480 if (ret != -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4481 if ((st_mode & S_IFMT) == S_IFDIR) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4482 errno = EISDIR;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4483 ::close(fd);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4484 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4485 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4486 } else {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4487 ::close(fd);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4488 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4489 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4490 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4491
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4492 /*
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4493 * All file descriptors that are opened in the JVM and not
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4494 * specifically destined for a subprocess should have the
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4495 * close-on-exec flag set. If we don't set it, then careless 3rd
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4496 * party native code might fork and exec without closing all
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4497 * appropriate file descriptors (e.g. as we do in closeDescriptors in
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4498 * UNIXProcess.c), and this in turn might:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4499 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4500 * - cause end-of-file to fail to be detected on some file
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4501 * descriptors, resulting in mysterious hangs, or
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4502 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4503 * - might cause an fopen in the subprocess to fail on a system
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4504 * suffering from bug 1085341.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4505 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4506 * (Yes, the default setting of the close-on-exec flag is a Unix
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4507 * design flaw)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4508 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4509 * See:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4510 * 1085341: 32-bit stdio routines should support file descriptors >255
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4511 * 4843136: (process) pipe file descriptor from Runtime.exec not being closed
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4512 * 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4513 */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4514 #ifdef FD_CLOEXEC
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4515 {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4516 int flags = ::fcntl(fd, F_GETFD);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4517 if (flags != -1)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4518 ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4519 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4520 #endif
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4521
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4522 if (o_delete != 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4523 ::unlink(path);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4524 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4525 return fd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4526 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4527
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4528
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4529 // create binary file, rewriting existing file if required
a61af66fc99e Initial load
duke
parents:
diff changeset
4530 int os::create_binary_file(const char* path, bool rewrite_existing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4531 int oflags = O_WRONLY | O_CREAT;
a61af66fc99e Initial load
duke
parents:
diff changeset
4532 if (!rewrite_existing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4533 oflags |= O_EXCL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4535 return ::open64(path, oflags, S_IREAD | S_IWRITE);
a61af66fc99e Initial load
duke
parents:
diff changeset
4536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4537
a61af66fc99e Initial load
duke
parents:
diff changeset
4538 // return current position of file pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
4539 jlong os::current_file_offset(int fd) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4540 return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);
a61af66fc99e Initial load
duke
parents:
diff changeset
4541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4542
a61af66fc99e Initial load
duke
parents:
diff changeset
4543 // move file pointer to the specified offset
a61af66fc99e Initial load
duke
parents:
diff changeset
4544 jlong os::seek_to_file_offset(int fd, jlong offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4545 return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);
a61af66fc99e Initial load
duke
parents:
diff changeset
4546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4547
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4548 // This code originates from JDK's sysAvailable
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4549 // from src/solaris/hpi/src/native_threads/src/sys_api_td.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4550
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4551 int os::available(int fd, jlong *bytes) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4552 jlong cur, end;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4553 int mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4554 struct stat64 buf64;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4555
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4556 if (::fstat64(fd, &buf64) >= 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4557 mode = buf64.st_mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4558 if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4559 /*
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4560 * XXX: is the following call interruptible? If so, this might
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4561 * need to go through the INTERRUPT_IO() wrapper as for other
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4562 * blocking, interruptible calls in this file.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4563 */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4564 int n;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4565 if (::ioctl(fd, FIONREAD, &n) >= 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4566 *bytes = n;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4567 return 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4568 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4569 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4570 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4571 if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4572 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4573 } else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4574 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4575 } else if (::lseek64(fd, cur, SEEK_SET) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4576 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4577 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4578 *bytes = end - cur;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4579 return 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4580 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4581
2033
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
4582 int os::socket_available(int fd, jint *pbytes) {
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
4583 // Linux doc says EINTR not returned, unlike Solaris
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
4584 int ret = ::ioctl(fd, FIONREAD, pbytes);
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
4585
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
4586 //%% note ioctl can return 0 when successful, JVM_SocketAvailable
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
4587 // is expected to return 0 on failure and 1 on success to the jdk.
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
4588 return (ret < 0) ? 0 : 1;
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
4589 }
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
4590
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4591 // Map a block of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
4592 char* os::map_memory(int fd, const char* file_name, size_t file_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
4593 char *addr, size_t bytes, bool read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
4594 bool allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4595 int prot;
a61af66fc99e Initial load
duke
parents:
diff changeset
4596 int flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
4597
a61af66fc99e Initial load
duke
parents:
diff changeset
4598 if (read_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4599 prot = PROT_READ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4600 flags = MAP_SHARED;
a61af66fc99e Initial load
duke
parents:
diff changeset
4601 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4602 prot = PROT_READ | PROT_WRITE;
a61af66fc99e Initial load
duke
parents:
diff changeset
4603 flags = MAP_PRIVATE;
a61af66fc99e Initial load
duke
parents:
diff changeset
4604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4605
a61af66fc99e Initial load
duke
parents:
diff changeset
4606 if (allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4607 prot |= PROT_EXEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
4608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4609
a61af66fc99e Initial load
duke
parents:
diff changeset
4610 if (addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4611 flags |= MAP_FIXED;
a61af66fc99e Initial load
duke
parents:
diff changeset
4612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4613
a61af66fc99e Initial load
duke
parents:
diff changeset
4614 char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
a61af66fc99e Initial load
duke
parents:
diff changeset
4615 fd, file_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
4616 if (mapped_address == MAP_FAILED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4617 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4619 return mapped_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
4620 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4621
a61af66fc99e Initial load
duke
parents:
diff changeset
4622
a61af66fc99e Initial load
duke
parents:
diff changeset
4623 // Remap a block of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
4624 char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
a61af66fc99e Initial load
duke
parents:
diff changeset
4625 char *addr, size_t bytes, bool read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
4626 bool allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4627 // same as map_memory() on this OS
a61af66fc99e Initial load
duke
parents:
diff changeset
4628 return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
4629 allow_exec);
a61af66fc99e Initial load
duke
parents:
diff changeset
4630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4631
a61af66fc99e Initial load
duke
parents:
diff changeset
4632
a61af66fc99e Initial load
duke
parents:
diff changeset
4633 // Unmap a block of memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
4634 bool os::unmap_memory(char* addr, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4635 return munmap(addr, bytes) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4637
a61af66fc99e Initial load
duke
parents:
diff changeset
4638 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
4639
a61af66fc99e Initial load
duke
parents:
diff changeset
4640 static clockid_t thread_cpu_clockid(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4641 pthread_t tid = thread->osthread()->pthread_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
4642 clockid_t clockid;
a61af66fc99e Initial load
duke
parents:
diff changeset
4643
a61af66fc99e Initial load
duke
parents:
diff changeset
4644 // Get thread clockid
a61af66fc99e Initial load
duke
parents:
diff changeset
4645 int rc = os::Linux::pthread_getcpuclockid(tid, &clockid);
a61af66fc99e Initial load
duke
parents:
diff changeset
4646 assert(rc == 0, "pthread_getcpuclockid is expected to return 0 code");
a61af66fc99e Initial load
duke
parents:
diff changeset
4647 return clockid;
a61af66fc99e Initial load
duke
parents:
diff changeset
4648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4649
a61af66fc99e Initial load
duke
parents:
diff changeset
4650 // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
a61af66fc99e Initial load
duke
parents:
diff changeset
4651 // are used by JVM M&M and JVMTI to get user+sys or user CPU time
a61af66fc99e Initial load
duke
parents:
diff changeset
4652 // of a thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
4653 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4654 // current_thread_cpu_time() and thread_cpu_time(Thread*) returns
a61af66fc99e Initial load
duke
parents:
diff changeset
4655 // the fast estimate available on the platform.
a61af66fc99e Initial load
duke
parents:
diff changeset
4656
a61af66fc99e Initial load
duke
parents:
diff changeset
4657 jlong os::current_thread_cpu_time() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4658 if (os::Linux::supports_fast_thread_cpu_time()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4659 return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
4660 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4661 // return user + sys since the cost is the same
a61af66fc99e Initial load
duke
parents:
diff changeset
4662 return slow_thread_cpu_time(Thread::current(), true /* user + sys */);
a61af66fc99e Initial load
duke
parents:
diff changeset
4663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4665
a61af66fc99e Initial load
duke
parents:
diff changeset
4666 jlong os::thread_cpu_time(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4667 // consistent with what current_thread_cpu_time() returns
a61af66fc99e Initial load
duke
parents:
diff changeset
4668 if (os::Linux::supports_fast_thread_cpu_time()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4669 return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
a61af66fc99e Initial load
duke
parents:
diff changeset
4670 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4671 return slow_thread_cpu_time(thread, true /* user + sys */);
a61af66fc99e Initial load
duke
parents:
diff changeset
4672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4674
a61af66fc99e Initial load
duke
parents:
diff changeset
4675 jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4676 if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4677 return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
4678 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4679 return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
4680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4682
a61af66fc99e Initial load
duke
parents:
diff changeset
4683 jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4684 if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4685 return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
a61af66fc99e Initial load
duke
parents:
diff changeset
4686 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4687 return slow_thread_cpu_time(thread, user_sys_cpu_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
4688 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4690
a61af66fc99e Initial load
duke
parents:
diff changeset
4691 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4692 // -1 on error.
a61af66fc99e Initial load
duke
parents:
diff changeset
4693 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4694
a61af66fc99e Initial load
duke
parents:
diff changeset
4695 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4696 static bool proc_pid_cpu_avail = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4697 static bool proc_task_unchecked = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4698 static const char *proc_stat_path = "/proc/%d/stat";
a61af66fc99e Initial load
duke
parents:
diff changeset
4699 pid_t tid = thread->osthread()->thread_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
4700 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
4701 char *s;
a61af66fc99e Initial load
duke
parents:
diff changeset
4702 char stat[2048];
a61af66fc99e Initial load
duke
parents:
diff changeset
4703 int statlen;
a61af66fc99e Initial load
duke
parents:
diff changeset
4704 char proc_name[64];
a61af66fc99e Initial load
duke
parents:
diff changeset
4705 int count;
a61af66fc99e Initial load
duke
parents:
diff changeset
4706 long sys_time, user_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
4707 char string[64];
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4708 char cdummy;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4709 int idummy;
a61af66fc99e Initial load
duke
parents:
diff changeset
4710 long ldummy;
a61af66fc99e Initial load
duke
parents:
diff changeset
4711 FILE *fp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4712
a61af66fc99e Initial load
duke
parents:
diff changeset
4713 // We first try accessing /proc/<pid>/cpu since this is faster to
a61af66fc99e Initial load
duke
parents:
diff changeset
4714 // process. If this file is not present (linux kernels 2.5 and above)
a61af66fc99e Initial load
duke
parents:
diff changeset
4715 // then we open /proc/<pid>/stat.
a61af66fc99e Initial load
duke
parents:
diff changeset
4716 if ( proc_pid_cpu_avail ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4717 sprintf(proc_name, "/proc/%d/cpu", tid);
a61af66fc99e Initial load
duke
parents:
diff changeset
4718 fp = fopen(proc_name, "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
4719 if ( fp != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4720 count = fscanf( fp, "%s %lu %lu\n", string, &user_time, &sys_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
4721 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
4722 if ( count != 3 ) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4723
a61af66fc99e Initial load
duke
parents:
diff changeset
4724 if (user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4725 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
a61af66fc99e Initial load
duke
parents:
diff changeset
4726 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4727 return (jlong)user_time * (1000000000 / clock_tics_per_sec);
a61af66fc99e Initial load
duke
parents:
diff changeset
4728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4730 else proc_pid_cpu_avail = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4732
a61af66fc99e Initial load
duke
parents:
diff changeset
4733 // The /proc/<tid>/stat aggregates per-process usage on
a61af66fc99e Initial load
duke
parents:
diff changeset
4734 // new Linux kernels 2.6+ where NPTL is supported.
a61af66fc99e Initial load
duke
parents:
diff changeset
4735 // The /proc/self/task/<tid>/stat still has the per-thread usage.
a61af66fc99e Initial load
duke
parents:
diff changeset
4736 // See bug 6328462.
a61af66fc99e Initial load
duke
parents:
diff changeset
4737 // There can be no directory /proc/self/task on kernels 2.4 with NPTL
a61af66fc99e Initial load
duke
parents:
diff changeset
4738 // and possibly in some other cases, so we check its availability.
a61af66fc99e Initial load
duke
parents:
diff changeset
4739 if (proc_task_unchecked && os::Linux::is_NPTL()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4740 // This is executed only once
a61af66fc99e Initial load
duke
parents:
diff changeset
4741 proc_task_unchecked = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4742 fp = fopen("/proc/self/task", "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
4743 if (fp != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4744 proc_stat_path = "/proc/self/task/%d/stat";
a61af66fc99e Initial load
duke
parents:
diff changeset
4745 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
4746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4748
a61af66fc99e Initial load
duke
parents:
diff changeset
4749 sprintf(proc_name, proc_stat_path, tid);
a61af66fc99e Initial load
duke
parents:
diff changeset
4750 fp = fopen(proc_name, "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
4751 if ( fp == NULL ) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4752 statlen = fread(stat, 1, 2047, fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
4753 stat[statlen] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
4754 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
4755
a61af66fc99e Initial load
duke
parents:
diff changeset
4756 // Skip pid and the command string. Note that we could be dealing with
a61af66fc99e Initial load
duke
parents:
diff changeset
4757 // weird command names, e.g. user could decide to rename java launcher
a61af66fc99e Initial load
duke
parents:
diff changeset
4758 // to "java 1.4.2 :)", then the stat file would look like
a61af66fc99e Initial load
duke
parents:
diff changeset
4759 // 1234 (java 1.4.2 :)) R ... ...
a61af66fc99e Initial load
duke
parents:
diff changeset
4760 // We don't really need to know the command string, just find the last
a61af66fc99e Initial load
duke
parents:
diff changeset
4761 // occurrence of ")" and then start parsing from there. See bug 4726580.
a61af66fc99e Initial load
duke
parents:
diff changeset
4762 s = strrchr(stat, ')');
a61af66fc99e Initial load
duke
parents:
diff changeset
4763 i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4764 if (s == NULL ) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4765
a61af66fc99e Initial load
duke
parents:
diff changeset
4766 // Skip blank chars
a61af66fc99e Initial load
duke
parents:
diff changeset
4767 do s++; while (isspace(*s));
a61af66fc99e Initial load
duke
parents:
diff changeset
4768
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4769 count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4770 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4771 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy,
a61af66fc99e Initial load
duke
parents:
diff changeset
4772 &user_time, &sys_time);
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4773 if ( count != 13 ) return -1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4774 if (user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4775 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
a61af66fc99e Initial load
duke
parents:
diff changeset
4776 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4777 return (jlong)user_time * (1000000000 / clock_tics_per_sec);
a61af66fc99e Initial load
duke
parents:
diff changeset
4778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4780
a61af66fc99e Initial load
duke
parents:
diff changeset
4781 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4782 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
4783 info_ptr->may_skip_backward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
4784 info_ptr->may_skip_forward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
4785 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned
a61af66fc99e Initial load
duke
parents:
diff changeset
4786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4787
a61af66fc99e Initial load
duke
parents:
diff changeset
4788 void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4789 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
4790 info_ptr->may_skip_backward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
4791 info_ptr->may_skip_forward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
4792 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned
a61af66fc99e Initial load
duke
parents:
diff changeset
4793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4794
a61af66fc99e Initial load
duke
parents:
diff changeset
4795 bool os::is_thread_cpu_time_supported() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4796 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4797 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4798
a61af66fc99e Initial load
duke
parents:
diff changeset
4799 // System loadavg support. Returns -1 if load average cannot be obtained.
a61af66fc99e Initial load
duke
parents:
diff changeset
4800 // Linux doesn't yet have a (official) notion of processor sets,
a61af66fc99e Initial load
duke
parents:
diff changeset
4801 // so just return the system wide load average.
a61af66fc99e Initial load
duke
parents:
diff changeset
4802 int os::loadavg(double loadavg[], int nelem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4803 return ::getloadavg(loadavg, nelem);
a61af66fc99e Initial load
duke
parents:
diff changeset
4804 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4805
a61af66fc99e Initial load
duke
parents:
diff changeset
4806 void os::pause() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4807 char filename[MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
4808 if (PauseAtStartupFile && PauseAtStartupFile[0]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4809 jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
a61af66fc99e Initial load
duke
parents:
diff changeset
4810 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4811 jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
4812 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4813
a61af66fc99e Initial load
duke
parents:
diff changeset
4814 int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
a61af66fc99e Initial load
duke
parents:
diff changeset
4815 if (fd != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4816 struct stat buf;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4817 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4818 while (::stat(filename, &buf) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4819 (void)::poll(NULL, 0, 100);
a61af66fc99e Initial load
duke
parents:
diff changeset
4820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4821 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4822 jio_fprintf(stderr,
a61af66fc99e Initial load
duke
parents:
diff changeset
4823 "Could not open pause file '%s', continuing immediately.\n", filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
4824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4826
a61af66fc99e Initial load
duke
parents:
diff changeset
4827
a61af66fc99e Initial load
duke
parents:
diff changeset
4828 // Refer to the comments in os_solaris.cpp park-unpark.
a61af66fc99e Initial load
duke
parents:
diff changeset
4829 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4830 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
a61af66fc99e Initial load
duke
parents:
diff changeset
4831 // hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
a61af66fc99e Initial load
duke
parents:
diff changeset
4832 // For specifics regarding the bug see GLIBC BUGID 261237 :
a61af66fc99e Initial load
duke
parents:
diff changeset
4833 // http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html.
a61af66fc99e Initial load
duke
parents:
diff changeset
4834 // Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future
a61af66fc99e Initial load
duke
parents:
diff changeset
4835 // will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar
a61af66fc99e Initial load
duke
parents:
diff changeset
4836 // is used. (The simple C test-case provided in the GLIBC bug report manifests the
a61af66fc99e Initial load
duke
parents:
diff changeset
4837 // hang). The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos()
a61af66fc99e Initial load
duke
parents:
diff changeset
4838 // and monitorenter when we're using 1-0 locking. All those operations may result in
a61af66fc99e Initial load
duke
parents:
diff changeset
4839 // calls to pthread_cond_timedwait(). Using LD_ASSUME_KERNEL to use an older version
a61af66fc99e Initial load
duke
parents:
diff changeset
4840 // of libpthread avoids the problem, but isn't practical.
a61af66fc99e Initial load
duke
parents:
diff changeset
4841 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4842 // Possible remedies:
a61af66fc99e Initial load
duke
parents:
diff changeset
4843 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4844 // 1. Establish a minimum relative wait time. 50 to 100 msecs seems to work.
a61af66fc99e Initial load
duke
parents:
diff changeset
4845 // This is palliative and probabilistic, however. If the thread is preempted
a61af66fc99e Initial load
duke
parents:
diff changeset
4846 // between the call to compute_abstime() and pthread_cond_timedwait(), more
a61af66fc99e Initial load
duke
parents:
diff changeset
4847 // than the minimum period may have passed, and the abstime may be stale (in the
a61af66fc99e Initial load
duke
parents:
diff changeset
4848 // past) resultin in a hang. Using this technique reduces the odds of a hang
a61af66fc99e Initial load
duke
parents:
diff changeset
4849 // but the JVM is still vulnerable, particularly on heavily loaded systems.
a61af66fc99e Initial load
duke
parents:
diff changeset
4850 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4851 // 2. Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead
a61af66fc99e Initial load
duke
parents:
diff changeset
4852 // of the usual flag-condvar-mutex idiom. The write side of the pipe is set
a61af66fc99e Initial load
duke
parents:
diff changeset
4853 // NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo)
a61af66fc99e Initial load
duke
parents:
diff changeset
4854 // reduces to poll()+read(). This works well, but consumes 2 FDs per extant
a61af66fc99e Initial load
duke
parents:
diff changeset
4855 // thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
4856 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4857 // 3. Embargo pthread_cond_timedwait() and implement a native "chron" thread
a61af66fc99e Initial load
duke
parents:
diff changeset
4858 // that manages timeouts. We'd emulate pthread_cond_timedwait() by enqueuing
a61af66fc99e Initial load
duke
parents:
diff changeset
4859 // a timeout request to the chron thread and then blocking via pthread_cond_wait().
a61af66fc99e Initial load
duke
parents:
diff changeset
4860 // This also works well. In fact it avoids kernel-level scalability impediments
a61af66fc99e Initial load
duke
parents:
diff changeset
4861 // on certain platforms that don't handle lots of active pthread_cond_timedwait()
a61af66fc99e Initial load
duke
parents:
diff changeset
4862 // timers in a graceful fashion.
a61af66fc99e Initial load
duke
parents:
diff changeset
4863 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4864 // 4. When the abstime value is in the past it appears that control returns
a61af66fc99e Initial load
duke
parents:
diff changeset
4865 // correctly from pthread_cond_timedwait(), but the condvar is left corrupt.
a61af66fc99e Initial load
duke
parents:
diff changeset
4866 // Subsequent timedwait/wait calls may hang indefinitely. Given that, we
a61af66fc99e Initial load
duke
parents:
diff changeset
4867 // can avoid the problem by reinitializing the condvar -- by cond_destroy()
a61af66fc99e Initial load
duke
parents:
diff changeset
4868 // followed by cond_init() -- after all calls to pthread_cond_timedwait().
a61af66fc99e Initial load
duke
parents:
diff changeset
4869 // It may be possible to avoid reinitialization by checking the return
a61af66fc99e Initial load
duke
parents:
diff changeset
4870 // value from pthread_cond_timedwait(). In addition to reinitializing the
a61af66fc99e Initial load
duke
parents:
diff changeset
4871 // condvar we must establish the invariant that cond_signal() is only called
a61af66fc99e Initial load
duke
parents:
diff changeset
4872 // within critical sections protected by the adjunct mutex. This prevents
a61af66fc99e Initial load
duke
parents:
diff changeset
4873 // cond_signal() from "seeing" a condvar that's in the midst of being
a61af66fc99e Initial load
duke
parents:
diff changeset
4874 // reinitialized or that is corrupt. Sadly, this invariant obviates the
a61af66fc99e Initial load
duke
parents:
diff changeset
4875 // desirable signal-after-unlock optimization that avoids futile context switching.
a61af66fc99e Initial load
duke
parents:
diff changeset
4876 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4877 // I'm also concerned that some versions of NTPL might allocate an auxilliary
a61af66fc99e Initial load
duke
parents:
diff changeset
4878 // structure when a condvar is used or initialized. cond_destroy() would
a61af66fc99e Initial load
duke
parents:
diff changeset
4879 // release the helper structure. Our reinitialize-after-timedwait fix
a61af66fc99e Initial load
duke
parents:
diff changeset
4880 // put excessive stress on malloc/free and locks protecting the c-heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
4881 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4882 // We currently use (4). See the WorkAroundNTPLTimedWaitHang flag.
a61af66fc99e Initial load
duke
parents:
diff changeset
4883 // It may be possible to refine (4) by checking the kernel and NTPL verisons
a61af66fc99e Initial load
duke
parents:
diff changeset
4884 // and only enabling the work-around for vulnerable environments.
a61af66fc99e Initial load
duke
parents:
diff changeset
4885
a61af66fc99e Initial load
duke
parents:
diff changeset
4886 // utility to compute the abstime argument to timedwait:
a61af66fc99e Initial load
duke
parents:
diff changeset
4887 // millis is the relative timeout time
a61af66fc99e Initial load
duke
parents:
diff changeset
4888 // abstime will be the absolute timeout time
a61af66fc99e Initial load
duke
parents:
diff changeset
4889 // TODO: replace compute_abstime() with unpackTime()
a61af66fc99e Initial load
duke
parents:
diff changeset
4890
a61af66fc99e Initial load
duke
parents:
diff changeset
4891 static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4892 if (millis < 0) millis = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4893 struct timeval now;
a61af66fc99e Initial load
duke
parents:
diff changeset
4894 int status = gettimeofday(&now, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4895 assert(status == 0, "gettimeofday");
a61af66fc99e Initial load
duke
parents:
diff changeset
4896 jlong seconds = millis / 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
4897 millis %= 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
4898 if (seconds > 50000000) { // see man cond_timedwait(3T)
a61af66fc99e Initial load
duke
parents:
diff changeset
4899 seconds = 50000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
4900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4901 abstime->tv_sec = now.tv_sec + seconds;
a61af66fc99e Initial load
duke
parents:
diff changeset
4902 long usec = now.tv_usec + millis * 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
4903 if (usec >= 1000000) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4904 abstime->tv_sec += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4905 usec -= 1000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
4906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4907 abstime->tv_nsec = usec * 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
4908 return abstime;
a61af66fc99e Initial load
duke
parents:
diff changeset
4909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4910
a61af66fc99e Initial load
duke
parents:
diff changeset
4911
a61af66fc99e Initial load
duke
parents:
diff changeset
4912 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
4913 // Conceptually TryPark() should be equivalent to park(0).
a61af66fc99e Initial load
duke
parents:
diff changeset
4914
a61af66fc99e Initial load
duke
parents:
diff changeset
4915 int os::PlatformEvent::TryPark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4916 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4917 const int v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4918 guarantee ((v == 0) || (v == 1), "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4919 if (Atomic::cmpxchg (0, &_Event, v) == v) return v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4922
a61af66fc99e Initial load
duke
parents:
diff changeset
4923 void os::PlatformEvent::park() { // AKA "down()"
a61af66fc99e Initial load
duke
parents:
diff changeset
4924 // Invariant: Only the thread associated with the Event/PlatformEvent
a61af66fc99e Initial load
duke
parents:
diff changeset
4925 // may call park().
a61af66fc99e Initial load
duke
parents:
diff changeset
4926 // TODO: assert that _Assoc != NULL or _Assoc == Self
a61af66fc99e Initial load
duke
parents:
diff changeset
4927 int v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4928 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4929 v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4930 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4932 guarantee (v >= 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4933 if (v == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4934 // Do this the hard way by blocking ...
a61af66fc99e Initial load
duke
parents:
diff changeset
4935 int status = pthread_mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
4936 assert_status(status == 0, status, "mutex_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
4937 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4938 ++ _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4939 while (_Event < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4940 status = pthread_cond_wait(_cond, _mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
4941 // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
a61af66fc99e Initial load
duke
parents:
diff changeset
4942 // Treat this the same as if the wait was interrupted
a61af66fc99e Initial load
duke
parents:
diff changeset
4943 if (status == ETIME) { status = EINTR; }
a61af66fc99e Initial load
duke
parents:
diff changeset
4944 assert_status(status == 0 || status == EINTR, status, "cond_wait");
a61af66fc99e Initial load
duke
parents:
diff changeset
4945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4946 -- _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4947
a61af66fc99e Initial load
duke
parents:
diff changeset
4948 // In theory we could move the ST of 0 into _Event past the unlock(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4949 // but then we'd need a MEMBAR after the ST.
a61af66fc99e Initial load
duke
parents:
diff changeset
4950 _Event = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4951 status = pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
4952 assert_status(status == 0, status, "mutex_unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
4953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4954 guarantee (_Event >= 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4956
a61af66fc99e Initial load
duke
parents:
diff changeset
4957 int os::PlatformEvent::park(jlong millis) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4958 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4959
a61af66fc99e Initial load
duke
parents:
diff changeset
4960 int v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4961 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4962 v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4963 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4965 guarantee (v >= 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4966 if (v != 0) return OS_OK ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4967
a61af66fc99e Initial load
duke
parents:
diff changeset
4968 // We do this the hard way, by blocking the thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
4969 // Consider enforcing a minimum timeout value.
a61af66fc99e Initial load
duke
parents:
diff changeset
4970 struct timespec abst;
a61af66fc99e Initial load
duke
parents:
diff changeset
4971 compute_abstime(&abst, millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
4972
a61af66fc99e Initial load
duke
parents:
diff changeset
4973 int ret = OS_TIMEOUT;
a61af66fc99e Initial load
duke
parents:
diff changeset
4974 int status = pthread_mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
4975 assert_status(status == 0, status, "mutex_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
4976 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4977 ++_nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4978
a61af66fc99e Initial load
duke
parents:
diff changeset
4979 // Object.wait(timo) will return because of
a61af66fc99e Initial load
duke
parents:
diff changeset
4980 // (a) notification
a61af66fc99e Initial load
duke
parents:
diff changeset
4981 // (b) timeout
a61af66fc99e Initial load
duke
parents:
diff changeset
4982 // (c) thread.interrupt
a61af66fc99e Initial load
duke
parents:
diff changeset
4983 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4984 // Thread.interrupt and object.notify{All} both call Event::set.
a61af66fc99e Initial load
duke
parents:
diff changeset
4985 // That is, we treat thread.interrupt as a special case of notification.
a61af66fc99e Initial load
duke
parents:
diff changeset
4986 // The underlying Solaris implementation, cond_timedwait, admits
a61af66fc99e Initial load
duke
parents:
diff changeset
4987 // spurious/premature wakeups, but the JLS/JVM spec prevents the
a61af66fc99e Initial load
duke
parents:
diff changeset
4988 // JVM from making those visible to Java code. As such, we must
a61af66fc99e Initial load
duke
parents:
diff changeset
4989 // filter out spurious wakeups. We assume all ETIME returns are valid.
a61af66fc99e Initial load
duke
parents:
diff changeset
4990 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4991 // TODO: properly differentiate simultaneous notify+interrupt.
a61af66fc99e Initial load
duke
parents:
diff changeset
4992 // In that case, we should propagate the notify to another waiter.
a61af66fc99e Initial load
duke
parents:
diff changeset
4993
a61af66fc99e Initial load
duke
parents:
diff changeset
4994 while (_Event < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4995 status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst);
a61af66fc99e Initial load
duke
parents:
diff changeset
4996 if (status != 0 && WorkAroundNPTLTimedWaitHang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4997 pthread_cond_destroy (_cond);
a61af66fc99e Initial load
duke
parents:
diff changeset
4998 pthread_cond_init (_cond, NULL) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5000 assert_status(status == 0 || status == EINTR ||
a61af66fc99e Initial load
duke
parents:
diff changeset
5001 status == ETIME || status == ETIMEDOUT,
a61af66fc99e Initial load
duke
parents:
diff changeset
5002 status, "cond_timedwait");
a61af66fc99e Initial load
duke
parents:
diff changeset
5003 if (!FilterSpuriousWakeups) break ; // previous semantics
a61af66fc99e Initial load
duke
parents:
diff changeset
5004 if (status == ETIME || status == ETIMEDOUT) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5005 // We consume and ignore EINTR and spurious wakeups.
a61af66fc99e Initial load
duke
parents:
diff changeset
5006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5007 --_nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5008 if (_Event >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5009 ret = OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
5010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5011 _Event = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5012 status = pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5013 assert_status(status == 0, status, "mutex_unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
5014 assert (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5015 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
5016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5017
a61af66fc99e Initial load
duke
parents:
diff changeset
5018 void os::PlatformEvent::unpark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5019 int v, AnyWaiters ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5020 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5021 v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5022 if (v > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5023 // The LD of _Event could have reordered or be satisfied
a61af66fc99e Initial load
duke
parents:
diff changeset
5024 // by a read-aside from this processor's write buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
5025 // To avoid problems execute a barrier and then
a61af66fc99e Initial load
duke
parents:
diff changeset
5026 // ratify the value.
a61af66fc99e Initial load
duke
parents:
diff changeset
5027 OrderAccess::fence() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5028 if (_Event == v) return ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5029 continue ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5031 if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5033 if (v < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5034 // Wait for the thread associated with the event to vacate
a61af66fc99e Initial load
duke
parents:
diff changeset
5035 int status = pthread_mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5036 assert_status(status == 0, status, "mutex_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
5037 AnyWaiters = _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5038 assert (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5039 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5040 AnyWaiters = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5041 pthread_cond_signal (_cond);
a61af66fc99e Initial load
duke
parents:
diff changeset
5042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5043 status = pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5044 assert_status(status == 0, status, "mutex_unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
5045 if (AnyWaiters != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5046 status = pthread_cond_signal(_cond);
a61af66fc99e Initial load
duke
parents:
diff changeset
5047 assert_status(status == 0, status, "cond_signal");
a61af66fc99e Initial load
duke
parents:
diff changeset
5048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5049 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5050
a61af66fc99e Initial load
duke
parents:
diff changeset
5051 // Note that we signal() _after dropping the lock for "immortal" Events.
a61af66fc99e Initial load
duke
parents:
diff changeset
5052 // This is safe and avoids a common class of futile wakeups. In rare
a61af66fc99e Initial load
duke
parents:
diff changeset
5053 // circumstances this can cause a thread to return prematurely from
a61af66fc99e Initial load
duke
parents:
diff changeset
5054 // cond_{timed}wait() but the spurious wakeup is benign and the victim will
a61af66fc99e Initial load
duke
parents:
diff changeset
5055 // simply re-test the condition and re-park itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
5056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5057
a61af66fc99e Initial load
duke
parents:
diff changeset
5058
a61af66fc99e Initial load
duke
parents:
diff changeset
5059 // JSR166
a61af66fc99e Initial load
duke
parents:
diff changeset
5060 // -------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5061
a61af66fc99e Initial load
duke
parents:
diff changeset
5062 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
5063 * The solaris and linux implementations of park/unpark are fairly
a61af66fc99e Initial load
duke
parents:
diff changeset
5064 * conservative for now, but can be improved. They currently use a
a61af66fc99e Initial load
duke
parents:
diff changeset
5065 * mutex/condvar pair, plus a a count.
a61af66fc99e Initial load
duke
parents:
diff changeset
5066 * Park decrements count if > 0, else does a condvar wait. Unpark
a61af66fc99e Initial load
duke
parents:
diff changeset
5067 * sets count to 1 and signals condvar. Only one thread ever waits
a61af66fc99e Initial load
duke
parents:
diff changeset
5068 * on the condvar. Contention seen when trying to park implies that someone
a61af66fc99e Initial load
duke
parents:
diff changeset
5069 * is unparking you, so don't wait. And spurious returns are fine, so there
a61af66fc99e Initial load
duke
parents:
diff changeset
5070 * is no need to track notifications.
a61af66fc99e Initial load
duke
parents:
diff changeset
5071 */
a61af66fc99e Initial load
duke
parents:
diff changeset
5072
a61af66fc99e Initial load
duke
parents:
diff changeset
5073
a61af66fc99e Initial load
duke
parents:
diff changeset
5074 #define NANOSECS_PER_SEC 1000000000
a61af66fc99e Initial load
duke
parents:
diff changeset
5075 #define NANOSECS_PER_MILLISEC 1000000
a61af66fc99e Initial load
duke
parents:
diff changeset
5076 #define MAX_SECS 100000000
a61af66fc99e Initial load
duke
parents:
diff changeset
5077 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
5078 * This code is common to linux and solaris and will be moved to a
a61af66fc99e Initial load
duke
parents:
diff changeset
5079 * common place in dolphin.
a61af66fc99e Initial load
duke
parents:
diff changeset
5080 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5081 * The passed in time value is either a relative time in nanoseconds
a61af66fc99e Initial load
duke
parents:
diff changeset
5082 * or an absolute time in milliseconds. Either way it has to be unpacked
a61af66fc99e Initial load
duke
parents:
diff changeset
5083 * into suitable seconds and nanoseconds components and stored in the
a61af66fc99e Initial load
duke
parents:
diff changeset
5084 * given timespec structure.
a61af66fc99e Initial load
duke
parents:
diff changeset
5085 * Given time is a 64-bit value and the time_t used in the timespec is only
a61af66fc99e Initial load
duke
parents:
diff changeset
5086 * a signed-32-bit value (except on 64-bit Linux) we have to watch for
a61af66fc99e Initial load
duke
parents:
diff changeset
5087 * overflow if times way in the future are given. Further on Solaris versions
a61af66fc99e Initial load
duke
parents:
diff changeset
5088 * prior to 10 there is a restriction (see cond_timedwait) that the specified
a61af66fc99e Initial load
duke
parents:
diff changeset
5089 * number of seconds, in abstime, is less than current_time + 100,000,000.
a61af66fc99e Initial load
duke
parents:
diff changeset
5090 * As it will be 28 years before "now + 100000000" will overflow we can
a61af66fc99e Initial load
duke
parents:
diff changeset
5091 * ignore overflow and just impose a hard-limit on seconds using the value
a61af66fc99e Initial load
duke
parents:
diff changeset
5092 * of "now + 100,000,000". This places a limit on the timeout of about 3.17
a61af66fc99e Initial load
duke
parents:
diff changeset
5093 * years from "now".
a61af66fc99e Initial load
duke
parents:
diff changeset
5094 */
a61af66fc99e Initial load
duke
parents:
diff changeset
5095
a61af66fc99e Initial load
duke
parents:
diff changeset
5096 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5097 assert (time > 0, "convertTime");
a61af66fc99e Initial load
duke
parents:
diff changeset
5098
a61af66fc99e Initial load
duke
parents:
diff changeset
5099 struct timeval now;
a61af66fc99e Initial load
duke
parents:
diff changeset
5100 int status = gettimeofday(&now, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5101 assert(status == 0, "gettimeofday");
a61af66fc99e Initial load
duke
parents:
diff changeset
5102
a61af66fc99e Initial load
duke
parents:
diff changeset
5103 time_t max_secs = now.tv_sec + MAX_SECS;
a61af66fc99e Initial load
duke
parents:
diff changeset
5104
a61af66fc99e Initial load
duke
parents:
diff changeset
5105 if (isAbsolute) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5106 jlong secs = time / 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5107 if (secs > max_secs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5108 absTime->tv_sec = max_secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
5109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5110 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5111 absTime->tv_sec = secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
5112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5113 absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
5114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5115 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5116 jlong secs = time / NANOSECS_PER_SEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
5117 if (secs >= MAX_SECS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5118 absTime->tv_sec = max_secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
5119 absTime->tv_nsec = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5121 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5122 absTime->tv_sec = now.tv_sec + secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
5123 absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5124 if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5125 absTime->tv_nsec -= NANOSECS_PER_SEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
5126 ++absTime->tv_sec; // note: this must be <= max_secs
a61af66fc99e Initial load
duke
parents:
diff changeset
5127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5130 assert(absTime->tv_sec >= 0, "tv_sec < 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
5131 assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
a61af66fc99e Initial load
duke
parents:
diff changeset
5132 assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
5133 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
a61af66fc99e Initial load
duke
parents:
diff changeset
5134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5135
a61af66fc99e Initial load
duke
parents:
diff changeset
5136 void Parker::park(bool isAbsolute, jlong time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5137 // Optional fast-path check:
a61af66fc99e Initial load
duke
parents:
diff changeset
5138 // Return immediately if a permit is available.
a61af66fc99e Initial load
duke
parents:
diff changeset
5139 if (_counter > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5140 _counter = 0 ;
1117
95e9083cf4a7 6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents: 1010
diff changeset
5141 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5142 return ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5144
a61af66fc99e Initial load
duke
parents:
diff changeset
5145 Thread* thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
5146 assert(thread->is_Java_thread(), "Must be JavaThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
5147 JavaThread *jt = (JavaThread *)thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
5148
a61af66fc99e Initial load
duke
parents:
diff changeset
5149 // Optional optimization -- avoid state transitions if there's an interrupt pending.
a61af66fc99e Initial load
duke
parents:
diff changeset
5150 // Check interrupt before trying to wait
a61af66fc99e Initial load
duke
parents:
diff changeset
5151 if (Thread::is_interrupted(thread, false)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5152 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
5153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5154
a61af66fc99e Initial load
duke
parents:
diff changeset
5155 // Next, demultiplex/decode time arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
5156 timespec absTime;
1865
1c352af0135d 6763959: java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
acorn
parents: 1750
diff changeset
5157 if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5158 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
5159 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5160 if (time > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5161 unpackTime(&absTime, isAbsolute, time);
a61af66fc99e Initial load
duke
parents:
diff changeset
5162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5163
a61af66fc99e Initial load
duke
parents:
diff changeset
5164
a61af66fc99e Initial load
duke
parents:
diff changeset
5165 // Enter safepoint region
a61af66fc99e Initial load
duke
parents:
diff changeset
5166 // Beware of deadlocks such as 6317397.
a61af66fc99e Initial load
duke
parents:
diff changeset
5167 // The per-thread Parker:: mutex is a classic leaf-lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
5168 // In particular a thread must never block on the Threads_lock while
a61af66fc99e Initial load
duke
parents:
diff changeset
5169 // holding the Parker:: mutex. If safepoints are pending both the
a61af66fc99e Initial load
duke
parents:
diff changeset
5170 // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
5171 ThreadBlockInVM tbivm(jt);
a61af66fc99e Initial load
duke
parents:
diff changeset
5172
a61af66fc99e Initial load
duke
parents:
diff changeset
5173 // Don't wait if cannot get lock since interference arises from
a61af66fc99e Initial load
duke
parents:
diff changeset
5174 // unblocking. Also. check interrupt before trying wait
a61af66fc99e Initial load
duke
parents:
diff changeset
5175 if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5176 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
5177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5178
a61af66fc99e Initial load
duke
parents:
diff changeset
5179 int status ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5180 if (_counter > 0) { // no wait needed
a61af66fc99e Initial load
duke
parents:
diff changeset
5181 _counter = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5182 status = pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5183 assert (status == 0, "invariant") ;
1117
95e9083cf4a7 6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents: 1010
diff changeset
5184 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5185 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
5186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5187
a61af66fc99e Initial load
duke
parents:
diff changeset
5188 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
5189 // Don't catch signals while blocked; let the running threads have the signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
5190 // (This allows a debugger to break into the running thread.)
a61af66fc99e Initial load
duke
parents:
diff changeset
5191 sigset_t oldsigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
5192 sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals();
a61af66fc99e Initial load
duke
parents:
diff changeset
5193 pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
5194 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5195
a61af66fc99e Initial load
duke
parents:
diff changeset
5196 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
5197 jt->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
5198 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
a61af66fc99e Initial load
duke
parents:
diff changeset
5199
a61af66fc99e Initial load
duke
parents:
diff changeset
5200 if (time == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5201 status = pthread_cond_wait (_cond, _mutex) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5202 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5203 status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5204 if (status != 0 && WorkAroundNPTLTimedWaitHang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5205 pthread_cond_destroy (_cond) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5206 pthread_cond_init (_cond, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5209 assert_status(status == 0 || status == EINTR ||
a61af66fc99e Initial load
duke
parents:
diff changeset
5210 status == ETIME || status == ETIMEDOUT,
a61af66fc99e Initial load
duke
parents:
diff changeset
5211 status, "cond_timedwait");
a61af66fc99e Initial load
duke
parents:
diff changeset
5212
a61af66fc99e Initial load
duke
parents:
diff changeset
5213 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
5214 pthread_sigmask(SIG_SETMASK, &oldsigs, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5215 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5216
a61af66fc99e Initial load
duke
parents:
diff changeset
5217 _counter = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5218 status = pthread_mutex_unlock(_mutex) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5219 assert_status(status == 0, status, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5220 // If externally suspended while waiting, re-suspend
a61af66fc99e Initial load
duke
parents:
diff changeset
5221 if (jt->handle_special_suspend_equivalent_condition()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5222 jt->java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
5223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5224
1117
95e9083cf4a7 6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents: 1010
diff changeset
5225 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5227
a61af66fc99e Initial load
duke
parents:
diff changeset
5228 void Parker::unpark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5229 int s, status ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5230 status = pthread_mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5231 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5232 s = _counter;
a61af66fc99e Initial load
duke
parents:
diff changeset
5233 _counter = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5234 if (s < 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5235 if (WorkAroundNPTLTimedWaitHang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5236 status = pthread_cond_signal (_cond) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5237 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5238 status = pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5239 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5240 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5241 status = pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5242 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5243 status = pthread_cond_signal (_cond) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5244 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5246 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5247 pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5248 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5251
a61af66fc99e Initial load
duke
parents:
diff changeset
5252
a61af66fc99e Initial load
duke
parents:
diff changeset
5253 extern char** environ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5254
a61af66fc99e Initial load
duke
parents:
diff changeset
5255 #ifndef __NR_fork
a61af66fc99e Initial load
duke
parents:
diff changeset
5256 #define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57)
a61af66fc99e Initial load
duke
parents:
diff changeset
5257 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5258
a61af66fc99e Initial load
duke
parents:
diff changeset
5259 #ifndef __NR_execve
a61af66fc99e Initial load
duke
parents:
diff changeset
5260 #define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59)
a61af66fc99e Initial load
duke
parents:
diff changeset
5261 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5262
a61af66fc99e Initial load
duke
parents:
diff changeset
5263 // Run the specified command in a separate process. Return its exit value,
a61af66fc99e Initial load
duke
parents:
diff changeset
5264 // or -1 on failure (e.g. can't fork a new process).
a61af66fc99e Initial load
duke
parents:
diff changeset
5265 // Unlike system(), this function can be called from signal handler. It
a61af66fc99e Initial load
duke
parents:
diff changeset
5266 // doesn't block SIGINT et al.
a61af66fc99e Initial load
duke
parents:
diff changeset
5267 int os::fork_and_exec(char* cmd) {
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
5268 const char * argv[4] = {"sh", "-c", cmd, NULL};
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5269
a61af66fc99e Initial load
duke
parents:
diff changeset
5270 // fork() in LinuxThreads/NPTL is not async-safe. It needs to run
a61af66fc99e Initial load
duke
parents:
diff changeset
5271 // pthread_atfork handlers and reset pthread library. All we need is a
a61af66fc99e Initial load
duke
parents:
diff changeset
5272 // separate process to execve. Make a direct syscall to fork process.
a61af66fc99e Initial load
duke
parents:
diff changeset
5273 // On IA64 there's no fork syscall, we have to use fork() and hope for
a61af66fc99e Initial load
duke
parents:
diff changeset
5274 // the best...
a61af66fc99e Initial load
duke
parents:
diff changeset
5275 pid_t pid = NOT_IA64(syscall(__NR_fork);)
a61af66fc99e Initial load
duke
parents:
diff changeset
5276 IA64_ONLY(fork();)
a61af66fc99e Initial load
duke
parents:
diff changeset
5277
a61af66fc99e Initial load
duke
parents:
diff changeset
5278 if (pid < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5279 // fork failed
a61af66fc99e Initial load
duke
parents:
diff changeset
5280 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5281
a61af66fc99e Initial load
duke
parents:
diff changeset
5282 } else if (pid == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5283 // child process
a61af66fc99e Initial load
duke
parents:
diff changeset
5284
a61af66fc99e Initial load
duke
parents:
diff changeset
5285 // execve() in LinuxThreads will call pthread_kill_other_threads_np()
a61af66fc99e Initial load
duke
parents:
diff changeset
5286 // first to kill every thread on the thread list. Because this list is
a61af66fc99e Initial load
duke
parents:
diff changeset
5287 // not reset by fork() (see notes above), execve() will instead kill
a61af66fc99e Initial load
duke
parents:
diff changeset
5288 // every thread in the parent process. We know this is the only thread
a61af66fc99e Initial load
duke
parents:
diff changeset
5289 // in the new process, so make a system call directly.
a61af66fc99e Initial load
duke
parents:
diff changeset
5290 // IA64 should use normal execve() from glibc to match the glibc fork()
a61af66fc99e Initial load
duke
parents:
diff changeset
5291 // above.
a61af66fc99e Initial load
duke
parents:
diff changeset
5292 NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
5293 IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5294
a61af66fc99e Initial load
duke
parents:
diff changeset
5295 // execve failed
a61af66fc99e Initial load
duke
parents:
diff changeset
5296 _exit(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
5297
a61af66fc99e Initial load
duke
parents:
diff changeset
5298 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5299 // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
5300 // care about the actual exit code, for now.
a61af66fc99e Initial load
duke
parents:
diff changeset
5301
a61af66fc99e Initial load
duke
parents:
diff changeset
5302 int status;
a61af66fc99e Initial load
duke
parents:
diff changeset
5303
a61af66fc99e Initial load
duke
parents:
diff changeset
5304 // Wait for the child process to exit. This returns immediately if
a61af66fc99e Initial load
duke
parents:
diff changeset
5305 // the child has already exited. */
a61af66fc99e Initial load
duke
parents:
diff changeset
5306 while (waitpid(pid, &status, 0) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5307 switch (errno) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5308 case ECHILD: return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5309 case EINTR: break;
a61af66fc99e Initial load
duke
parents:
diff changeset
5310 default: return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5312 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5313
a61af66fc99e Initial load
duke
parents:
diff changeset
5314 if (WIFEXITED(status)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5315 // The child exited normally; get its exit code.
a61af66fc99e Initial load
duke
parents:
diff changeset
5316 return WEXITSTATUS(status);
a61af66fc99e Initial load
duke
parents:
diff changeset
5317 } else if (WIFSIGNALED(status)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5318 // The child exited because of a signal
a61af66fc99e Initial load
duke
parents:
diff changeset
5319 // The best value to return is 0x80 + signal number,
a61af66fc99e Initial load
duke
parents:
diff changeset
5320 // because that is what all Unix shells do, and because
a61af66fc99e Initial load
duke
parents:
diff changeset
5321 // it allows callers to distinguish between process exit and
a61af66fc99e Initial load
duke
parents:
diff changeset
5322 // process death by signal.
a61af66fc99e Initial load
duke
parents:
diff changeset
5323 return 0x80 + WTERMSIG(status);
a61af66fc99e Initial load
duke
parents:
diff changeset
5324 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5325 // Unknown exit code; pass it through
a61af66fc99e Initial load
duke
parents:
diff changeset
5326 return status;
a61af66fc99e Initial load
duke
parents:
diff changeset
5327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5329 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5330
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5331 // is_headless_jre()
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5332 //
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5333 // Test for the existence of libmawt in motif21 or xawt directories
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5334 // in order to report if we are running in a headless jre
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5335 //
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5336 bool os::is_headless_jre() {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5337 struct stat statbuf;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5338 char buf[MAXPATHLEN];
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5339 char libmawtpath[MAXPATHLEN];
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5340 const char *xawtstr = "/xawt/libmawt.so";
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5341 const char *motifstr = "/motif21/libmawt.so";
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5342 char *p;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5343
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5344 // Get path to libjvm.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5345 os::jvm_path(buf, sizeof(buf));
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5346
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5347 // Get rid of libjvm.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5348 p = strrchr(buf, '/');
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5349 if (p == NULL) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5350 else *p = '\0';
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5351
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5352 // Get rid of client or server
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5353 p = strrchr(buf, '/');
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5354 if (p == NULL) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5355 else *p = '\0';
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5356
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5357 // check xawt/libmawt.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5358 strcpy(libmawtpath, buf);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5359 strcat(libmawtpath, xawtstr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5360 if (::stat(libmawtpath, &statbuf) == 0) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5361
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5362 // check motif21/libmawt.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5363 strcpy(libmawtpath, buf);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5364 strcat(libmawtpath, motifstr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5365 if (::stat(libmawtpath, &statbuf) == 0) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5366
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5367 return true;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5368 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5369