annotate src/os/linux/vm/os_linux.cpp @ 20338:8d5f66b42c53

8055525: Bigapp weblogic+medrec fails to startup after JDK-8038423 Summary: If large pages are enabled and configured in Linux, the VM always pre-commits the entire space. The VM fails verification of the commit of the initial heap because some internal data structure marked all memory pages of the heap as committed during initialization. This makes the code think that we attempted a double-commit during first allocation of the heap. Remove the initial marking of memory pages of the heap to committed. Reviewed-by: mgerdin
author tschatzl
date Wed, 20 Aug 2014 14:34:40 +0200
parents d22136881b85
children 833b0f92429a
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
17765
91dc38ae09f3 8033464: Linux code cleanup
dcubed
parents: 17738
diff changeset
2 * Copyright (c) 1999, 2014, 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
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
25 // no precompiled headers
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
26 #include "classfile/classLoader.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
27 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
28 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
29 #include "code/icBuffer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
30 #include "code/vtableStubs.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
31 #include "compiler/compileBroker.hpp"
7199
cd3d6a6b95d9 8003240: x86: move MacroAssembler into separate file
twisti
parents: 6966
diff changeset
32 #include "compiler/disassembler.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
33 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
34 #include "jvm_linux.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
35 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
36 #include "memory/filemap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
37 #include "mutex_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
38 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
39 #include "os_share_linux.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
40 #include "prims/jniFastGetField.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
41 #include "prims/jvm.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
42 #include "prims/jvm_misc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
43 #include "runtime/arguments.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
44 #include "runtime/extendedPC.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
45 #include "runtime/globals.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
46 #include "runtime/interfaceSupport.hpp"
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
47 #include "runtime/init.hpp"
1972
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"
20197
ce8f6bb717c9 8042195: Introduce umbrella header orderAccess.inline.hpp.
goetz
parents: 17937
diff changeset
52 #include "runtime/orderAccess.inline.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
53 #include "runtime/osThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
54 #include "runtime/perfMemory.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
55 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
56 #include "runtime/statSampler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
57 #include "runtime/stubRoutines.hpp"
7180
f34d701e952e 8003935: Simplify the needed includes for using Thread::current()
stefank
parents: 6966
diff changeset
58 #include "runtime/thread.inline.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
59 #include "runtime/threadCritical.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
60 #include "runtime/timer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
61 #include "services/attachListener.hpp"
8711
6b803ba47588 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 8710
diff changeset
62 #include "services/memTracker.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
63 #include "services/runtimeService.hpp"
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
64 #include "utilities/decoder.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
65 #include "utilities/defaultStream.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
66 #include "utilities/events.hpp"
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
67 #include "utilities/elfFile.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
68 #include "utilities/growableArray.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1867
diff changeset
69 #include "utilities/vmError.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // put OS-includes here
a61af66fc99e Initial load
duke
parents:
diff changeset
72 # include <sys/types.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
73 # include <sys/mman.h>
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
74 # include <sys/stat.h>
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
75 # include <sys/select.h>
0
a61af66fc99e Initial load
duke
parents:
diff changeset
76 # include <pthread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
77 # include <signal.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
78 # include <errno.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
79 # include <dlfcn.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
80 # include <stdio.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
81 # include <unistd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
82 # include <sys/resource.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
83 # include <pthread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
84 # include <sys/stat.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
85 # include <sys/time.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
86 # include <sys/times.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
87 # include <sys/utsname.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
88 # include <sys/socket.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
89 # include <sys/wait.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
90 # include <pwd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
91 # include <poll.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
92 # include <semaphore.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
93 # include <fcntl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
94 # include <string.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
95 # include <syscall.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
96 # include <sys/sysinfo.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
97 # include <gnu/libc-version.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
98 # include <sys/ipc.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
99 # include <sys/shm.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
100 # include <link.h>
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
101 # include <stdint.h>
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
102 # include <inttypes.h>
2033
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
103 # include <sys/ioctl.h>
0
a61af66fc99e Initial load
duke
parents:
diff changeset
104
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
105 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
106
10372
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
107 // if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
108 // getrusage() is prepared to handle the associated failure.
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
109 #ifndef RUSAGE_THREAD
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
110 #define RUSAGE_THREAD (1) /* only the calling thread */
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
111 #endif
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
112
0
a61af66fc99e Initial load
duke
parents:
diff changeset
113 #define MAX_PATH (2 * K)
a61af66fc99e Initial load
duke
parents:
diff changeset
114
17738
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
115 #define MAX_SECS 100000000
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
116
0
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // for timer info max values which include all bits
a61af66fc99e Initial load
duke
parents:
diff changeset
118 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
a61af66fc99e Initial load
duke
parents:
diff changeset
119
2204
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
120 #define LARGEPAGES_BIT (1 << 6)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
121 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // global variables
a61af66fc99e Initial load
duke
parents:
diff changeset
123 julong os::Linux::_physical_memory = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 address os::Linux::_initial_thread_stack_bottom = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
126 uintptr_t os::Linux::_initial_thread_stack_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 int (*os::Linux::_clock_gettime)(clockid_t, struct timespec *) = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
129 int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
130 Mutex* os::Linux::_createThread_lock = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 pthread_t os::Linux::_main_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 int os::Linux::_page_size = -1;
10164
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
133 const int os::Linux::_vm_default_page_size = (8 * K);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
134 bool os::Linux::_is_floating_stack = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
135 bool os::Linux::_is_NPTL = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 bool os::Linux::_supports_fast_thread_cpu_time = false;
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
137 const char * os::Linux::_glibc_version = NULL;
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
138 const char * os::Linux::_libpthread_version = NULL;
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
139 pthread_condattr_t os::Linux::_condattr[1];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 static jlong initial_time_count=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143 static int clock_tics_per_sec = 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // For diagnostics to print a message once. see run_periodic_checks
a61af66fc99e Initial load
duke
parents:
diff changeset
146 static sigset_t check_signal_done;
14391
d2907f74462e 8016586: PPC64 (part 3): basic changes for PPC64
goetz
parents: 14390
diff changeset
147 static bool check_signals = true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 static pid_t _initial_pid = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 /* Signal number used to suspend/resume a thread */
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 /* do not use any signal number less than SIGSEGV, see 4355769 */
a61af66fc99e Initial load
duke
parents:
diff changeset
154 static int SR_signum = SIGUSR2;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 sigset_t SR_sigset;
a61af66fc99e Initial load
duke
parents:
diff changeset
156
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
157 /* Used to protect dlsym() calls */
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
158 static pthread_mutex_t dl_mutex;
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
159
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
160 // Declarations
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
161 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
162
3802
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
163 #ifdef JAVASE_EMBEDDED
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
164 class MemNotifyThread: public Thread {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
165 friend class VMStructs;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
166 public:
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
167 virtual void run();
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
168
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
169 private:
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
170 static MemNotifyThread* _memnotify_thread;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
171 int _fd;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
172
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
173 public:
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
174
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
175 // Constructor
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
176 MemNotifyThread(int fd);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
177
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
178 // Tester
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
179 bool is_memnotify_thread() const { return true; }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
180
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
181 // Printing
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
182 char* name() const { return (char*)"Linux MemNotify Thread"; }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
183
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
184 // Returns the single instance of the MemNotifyThread
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
185 static MemNotifyThread* memnotify_thread() { return _memnotify_thread; }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
186
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
187 // Create and start the single instance of MemNotifyThread
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
188 static void start();
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
189 };
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
190 #endif // JAVASE_EMBEDDED
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
191
0
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // utility functions
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 static int SR_initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
195
a61af66fc99e Initial load
duke
parents:
diff changeset
196 julong os::available_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
197 return Linux::available_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199
a61af66fc99e Initial load
duke
parents:
diff changeset
200 julong os::Linux::available_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 // values in struct sysinfo are "unsigned long"
a61af66fc99e Initial load
duke
parents:
diff changeset
202 struct sysinfo si;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 sysinfo(&si);
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 return (julong)si.freeram * si.mem_unit;
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207
a61af66fc99e Initial load
duke
parents:
diff changeset
208 julong os::physical_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
209 return Linux::physical_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
213 // environment support
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 bool os::getenv(const char* name, char* buf, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 const char* val = ::getenv(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if (val != NULL && strlen(val) < (size_t)len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 strcpy(buf, val);
a61af66fc99e Initial load
duke
parents:
diff changeset
219 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221 if (len > 0) buf[0] = 0; // return a null string
a61af66fc99e Initial load
duke
parents:
diff changeset
222 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // Return true if user is running as root.
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 bool os::have_special_privileges() {
a61af66fc99e Initial load
duke
parents:
diff changeset
229 static bool init = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
230 static bool privileges = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 if (!init) {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 privileges = (getuid() != geteuid()) || (getgid() != getegid());
a61af66fc99e Initial load
duke
parents:
diff changeset
233 init = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235 return privileges;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
237
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 #ifndef SYS_gettid
a61af66fc99e Initial load
duke
parents:
diff changeset
240 // i386: 224, ia64: 1105, amd64: 186, sparc 143
a61af66fc99e Initial load
duke
parents:
diff changeset
241 #ifdef __ia64__
a61af66fc99e Initial load
duke
parents:
diff changeset
242 #define SYS_gettid 1105
a61af66fc99e Initial load
duke
parents:
diff changeset
243 #elif __i386__
a61af66fc99e Initial load
duke
parents:
diff changeset
244 #define SYS_gettid 224
a61af66fc99e Initial load
duke
parents:
diff changeset
245 #elif __amd64__
a61af66fc99e Initial load
duke
parents:
diff changeset
246 #define SYS_gettid 186
a61af66fc99e Initial load
duke
parents:
diff changeset
247 #elif __sparc__
a61af66fc99e Initial load
duke
parents:
diff changeset
248 #define SYS_gettid 143
a61af66fc99e Initial load
duke
parents:
diff changeset
249 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
250 #error define gettid for the arch
a61af66fc99e Initial load
duke
parents:
diff changeset
251 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
252 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // Cpu architecture string
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
255 #if defined(ZERO)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
256 static char cpu_arch[] = ZERO_LIBARCH;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
257 #elif defined(IA64)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
258 static char cpu_arch[] = "ia64";
a61af66fc99e Initial load
duke
parents:
diff changeset
259 #elif defined(IA32)
a61af66fc99e Initial load
duke
parents:
diff changeset
260 static char cpu_arch[] = "i386";
a61af66fc99e Initial load
duke
parents:
diff changeset
261 #elif defined(AMD64)
a61af66fc99e Initial load
duke
parents:
diff changeset
262 static char cpu_arch[] = "amd64";
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
263 #elif defined(ARM)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
264 static char cpu_arch[] = "arm";
14390
0f03ff49c720 8016491: PPC64 (part 2): Clean up PPC defines.
goetz
parents: 10208
diff changeset
265 #elif defined(PPC32)
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
266 static char cpu_arch[] = "ppc";
14391
d2907f74462e 8016586: PPC64 (part 3): basic changes for PPC64
goetz
parents: 14390
diff changeset
267 #elif defined(PPC64)
d2907f74462e 8016586: PPC64 (part 3): basic changes for PPC64
goetz
parents: 14390
diff changeset
268 static char cpu_arch[] = "ppc64";
0
a61af66fc99e Initial load
duke
parents:
diff changeset
269 #elif defined(SPARC)
a61af66fc99e Initial load
duke
parents:
diff changeset
270 # ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
271 static char cpu_arch[] = "sparcv9";
a61af66fc99e Initial load
duke
parents:
diff changeset
272 # else
a61af66fc99e Initial load
duke
parents:
diff changeset
273 static char cpu_arch[] = "sparc";
a61af66fc99e Initial load
duke
parents:
diff changeset
274 # endif
a61af66fc99e Initial load
duke
parents:
diff changeset
275 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
276 #error Add appropriate cpu_arch setting
a61af66fc99e Initial load
duke
parents:
diff changeset
277 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // pid_t gettid()
a61af66fc99e Initial load
duke
parents:
diff changeset
281 //
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // Returns the kernel thread id of the currently running thread. Kernel
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // thread id is used to access /proc.
a61af66fc99e Initial load
duke
parents:
diff changeset
284 //
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // (Note that getpid() on LinuxThreads returns kernel thread id too; but
a61af66fc99e Initial load
duke
parents:
diff changeset
286 // on NPTL, it returns the same pid for all threads, as required by POSIX.)
a61af66fc99e Initial load
duke
parents:
diff changeset
287 //
a61af66fc99e Initial load
duke
parents:
diff changeset
288 pid_t os::Linux::gettid() {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 int rslt = syscall(SYS_gettid);
a61af66fc99e Initial load
duke
parents:
diff changeset
290 if (rslt == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // old kernel, no NPTL support
a61af66fc99e Initial load
duke
parents:
diff changeset
292 return getpid();
a61af66fc99e Initial load
duke
parents:
diff changeset
293 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
294 return (pid_t)rslt;
a61af66fc99e Initial load
duke
parents:
diff changeset
295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // Most versions of linux have a bug where the number of processors are
a61af66fc99e Initial load
duke
parents:
diff changeset
299 // determined by looking at the /proc file system. In a chroot environment,
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // the system call returns 1. This causes the VM to act as if it is
a61af66fc99e Initial load
duke
parents:
diff changeset
301 // a single processor and elide locking (see is_MP() call).
a61af66fc99e Initial load
duke
parents:
diff changeset
302 static bool unsafe_chroot_detected = false;
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
303 static const char *unstable_chroot_error = "/proc file system not found.\n"
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
304 "Java may be unstable running multithreaded in a chroot "
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
305 "environment on Linux when /proc filesystem is not mounted.";
0
a61af66fc99e Initial load
duke
parents:
diff changeset
306
a61af66fc99e Initial load
duke
parents:
diff changeset
307 void os::Linux::initialize_system_info() {
1123
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 1117
diff changeset
308 set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 1117
diff changeset
309 if (processor_count() == 1) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
310 pid_t pid = os::Linux::gettid();
a61af66fc99e Initial load
duke
parents:
diff changeset
311 char fname[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
312 jio_snprintf(fname, sizeof(fname), "/proc/%d", pid);
a61af66fc99e Initial load
duke
parents:
diff changeset
313 FILE *fp = fopen(fname, "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
314 if (fp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 unsafe_chroot_detected = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
316 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
320 _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
1123
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 1117
diff changeset
321 assert(processor_count() > 0, "linux error");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323
a61af66fc99e Initial load
duke
parents:
diff changeset
324 void os::init_system_properties_values() {
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // The next steps are taken in the product version:
a61af66fc99e Initial load
duke
parents:
diff changeset
326 //
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
327 // Obtain the JAVA_HOME value from the location of libjvm.so.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // This library should be located at:
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
329 // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm.so.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
330 //
a61af66fc99e Initial load
duke
parents:
diff changeset
331 // If "/jre/lib/" appears at the right place in the path, then we
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
332 // assume libjvm.so is installed in a JDK and we use this path.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
333 //
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // Otherwise exit with message: "Could not create the Java virtual machine."
a61af66fc99e Initial load
duke
parents:
diff changeset
335 //
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // The following extra steps are taken in the debugging version:
a61af66fc99e Initial load
duke
parents:
diff changeset
337 //
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // If "/jre/lib/" does NOT appear at the right place in the path
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // instead of exit check for $JAVA_HOME environment variable.
a61af66fc99e Initial load
duke
parents:
diff changeset
340 //
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
342 // then we append a fake suffix "hotspot/libjvm.so" to this path so
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
343 // it looks like libjvm.so is installed there
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
344 // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
345 //
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // Otherwise exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
347 //
a61af66fc99e Initial load
duke
parents:
diff changeset
348 // Important note: if the location of libjvm.so changes this
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // code needs to be changed accordingly.
a61af66fc99e Initial load
duke
parents:
diff changeset
350
17848
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
351 // See ld(1):
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
352 // The linker uses the following search paths to locate required
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
353 // shared libraries:
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
354 // 1: ...
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
355 // ...
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
356 // 7: The default directories, normally /lib and /usr/lib.
509
9656bebe85a7 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 477
diff changeset
357 #if defined(AMD64) || defined(_LP64) && (defined(SPARC) || defined(PPC) || defined(S390))
9656bebe85a7 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 477
diff changeset
358 #define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib"
9656bebe85a7 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 477
diff changeset
359 #else
0
a61af66fc99e Initial load
duke
parents:
diff changeset
360 #define DEFAULT_LIBPATH "/lib:/usr/lib"
509
9656bebe85a7 6778662: fixes 64-bits libraries directory search paths on linux
kvn
parents: 477
diff changeset
361 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
362
17848
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
363 // Base path of extensions installed on the system.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
364 #define SYS_EXT_DIR "/usr/java/packages"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
365 #define EXTENSIONS_DIR "/lib/ext"
a61af66fc99e Initial load
duke
parents:
diff changeset
366 #define ENDORSED_DIR "/lib/endorsed"
17848
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
367
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
368 // Buffer that fits several sprintfs.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
369 // Note that the space for the colon and the trailing null are provided
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
370 // by the nulls included by the sizeof operator.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
371 const size_t bufsize =
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
372 MAX3((size_t)MAXPATHLEN, // For dll_dir & friends.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
373 (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR), // extensions dir
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
374 (size_t)MAXPATHLEN + sizeof(ENDORSED_DIR)); // endorsed dir
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
375 char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
376
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
377 // sysclasspath, java_home, dll_dir
0
a61af66fc99e Initial load
duke
parents:
diff changeset
378 {
17848
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
379 char *pslash;
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
380 os::jvm_path(buf, bufsize);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
381
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
382 // Found the full path to libjvm.so.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
383 // Now cut the path to <java_home>/jre if we can.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
384 *(strrchr(buf, '/')) = '\0'; // Get rid of /libjvm.so.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
385 pslash = strrchr(buf, '/');
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
386 if (pslash != NULL) {
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
387 *pslash = '\0'; // Get rid of /{client|server|hotspot}.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
388 }
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
389 Arguments::set_dll_dir(buf);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
390
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
391 if (pslash != NULL) {
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
392 pslash = strrchr(buf, '/');
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
393 if (pslash != NULL) {
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
394 *pslash = '\0'; // Get rid of /<arch>.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
395 pslash = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
396 if (pslash != NULL) {
17848
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
397 *pslash = '\0'; // Get rid of /lib.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
17848
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
399 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
17848
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
401 Arguments::set_java_home(buf);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
402 set_boot_path('/', ':');
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
403 }
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
404
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
405 // Where to look for native libraries.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
406 //
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
407 // Note: Due to a legacy implementation, most of the library path
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
408 // is set in the launcher. This was to accomodate linking restrictions
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
409 // on legacy Linux implementations (which are no longer supported).
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
410 // Eventually, all the library path setting will be done here.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
411 //
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
412 // However, to prevent the proliferation of improperly built native
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
413 // libraries, the new path component /usr/java/packages is added here.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
414 // Eventually, all the library path setting will be done here.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
415 {
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
416 // Get the user setting of LD_LIBRARY_PATH, and prepended it. It
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
417 // should always exist (until the legacy problem cited above is
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
418 // addressed).
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
419 const char *v = ::getenv("LD_LIBRARY_PATH");
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
420 const char *v_colon = ":";
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
421 if (v == NULL) { v = ""; v_colon = ""; }
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
422 // That's +1 for the colon and +1 for the trailing '\0'.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
423 char *ld_library_path = (char *)NEW_C_HEAP_ARRAY(char,
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
424 strlen(v) + 1 +
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
425 sizeof(SYS_EXT_DIR) + sizeof("/lib/") + strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH) + 1,
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
426 mtInternal);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
427 sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib/%s:" DEFAULT_LIBPATH, v, v_colon, cpu_arch);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
428 Arguments::set_library_path(ld_library_path);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
429 FREE_C_HEAP_ARRAY(char, ld_library_path, mtInternal);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
430 }
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
431
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
432 // Extensions directories.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
433 sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home());
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
434 Arguments::set_ext_dirs(buf);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
435
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
436 // Endorsed standards default directory.
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
437 sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
438 Arguments::set_endorsed_dirs(buf);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
439
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
440 FREE_C_HEAP_ARRAY(char, buf, mtInternal);
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
441
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
442 #undef DEFAULT_LIBPATH
6048424d3865 8038201: Clean up misleading usage of malloc() in init_system_properties_values()
goetz
parents: 17845
diff changeset
443 #undef SYS_EXT_DIR
0
a61af66fc99e Initial load
duke
parents:
diff changeset
444 #undef EXTENSIONS_DIR
a61af66fc99e Initial load
duke
parents:
diff changeset
445 #undef ENDORSED_DIR
a61af66fc99e Initial load
duke
parents:
diff changeset
446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
447
a61af66fc99e Initial load
duke
parents:
diff changeset
448 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
449 // breakpoint support
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 void os::breakpoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
452 BREAKPOINT;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 }
a61af66fc99e Initial load
duke
parents:
diff changeset
454
a61af66fc99e Initial load
duke
parents:
diff changeset
455 extern "C" void breakpoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 // use debugger to set breakpoint here
a61af66fc99e Initial load
duke
parents:
diff changeset
457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
460 // signal support
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 debug_only(static bool signal_sets_initialized = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
463 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
464
a61af66fc99e Initial load
duke
parents:
diff changeset
465 bool os::Linux::is_sig_ignored(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
466 struct sigaction oact;
a61af66fc99e Initial load
duke
parents:
diff changeset
467 sigaction(sig, (struct sigaction*)NULL, &oact);
a61af66fc99e Initial load
duke
parents:
diff changeset
468 void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
469 : CAST_FROM_FN_PTR(void*, oact.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
470 if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN))
a61af66fc99e Initial load
duke
parents:
diff changeset
471 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
472 else
a61af66fc99e Initial load
duke
parents:
diff changeset
473 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
475
a61af66fc99e Initial load
duke
parents:
diff changeset
476 void os::Linux::signal_sets_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // Should also have an assertion stating we are still single-threaded.
a61af66fc99e Initial load
duke
parents:
diff changeset
478 assert(!signal_sets_initialized, "Already initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
479 // Fill in signals that are necessarily unblocked for all threads in
a61af66fc99e Initial load
duke
parents:
diff changeset
480 // the VM. Currently, we unblock the following signals:
a61af66fc99e Initial load
duke
parents:
diff changeset
481 // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden
a61af66fc99e Initial load
duke
parents:
diff changeset
482 // by -Xrs (=ReduceSignalUsage));
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // other threads. The "ReduceSignalUsage" boolean tells us not to alter
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // the dispositions or masks wrt these signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // Programs embedding the VM that want to use the above signals for their
a61af66fc99e Initial load
duke
parents:
diff changeset
487 // own purposes must, at this time, use the "-Xrs" option to prevent
a61af66fc99e Initial load
duke
parents:
diff changeset
488 // interference with shutdown hooks and BREAK_SIGNAL thread dumping.
a61af66fc99e Initial load
duke
parents:
diff changeset
489 // (See bug 4345157, and other related bugs).
a61af66fc99e Initial load
duke
parents:
diff changeset
490 // In reality, though, unblocking these signals is really a nop, since
a61af66fc99e Initial load
duke
parents:
diff changeset
491 // these signals are not blocked by default.
a61af66fc99e Initial load
duke
parents:
diff changeset
492 sigemptyset(&unblocked_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
493 sigemptyset(&allowdebug_blocked_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
494 sigaddset(&unblocked_sigs, SIGILL);
a61af66fc99e Initial load
duke
parents:
diff changeset
495 sigaddset(&unblocked_sigs, SIGSEGV);
a61af66fc99e Initial load
duke
parents:
diff changeset
496 sigaddset(&unblocked_sigs, SIGBUS);
a61af66fc99e Initial load
duke
parents:
diff changeset
497 sigaddset(&unblocked_sigs, SIGFPE);
14432
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
498 #if defined(PPC64)
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
499 sigaddset(&unblocked_sigs, SIGTRAP);
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
500 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
501 sigaddset(&unblocked_sigs, SR_signum);
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 if (!os::Linux::is_sig_ignored(SHUTDOWN1_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
505 sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
506 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
508 if (!os::Linux::is_sig_ignored(SHUTDOWN2_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
510 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512 if (!os::Linux::is_sig_ignored(SHUTDOWN3_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
513 sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
514 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
517 // Fill in signals that are blocked by all but the VM thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
518 sigemptyset(&vm_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
519 if (!ReduceSignalUsage)
a61af66fc99e Initial load
duke
parents:
diff changeset
520 sigaddset(&vm_sigs, BREAK_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 debug_only(signal_sets_initialized = true);
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 }
a61af66fc99e Initial load
duke
parents:
diff changeset
524
a61af66fc99e Initial load
duke
parents:
diff changeset
525 // These are signals that are unblocked while a thread is running Java.
a61af66fc99e Initial load
duke
parents:
diff changeset
526 // (For some reason, they get blocked by default.)
a61af66fc99e Initial load
duke
parents:
diff changeset
527 sigset_t* os::Linux::unblocked_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
529 return &unblocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
530 }
a61af66fc99e Initial load
duke
parents:
diff changeset
531
a61af66fc99e Initial load
duke
parents:
diff changeset
532 // These are the signals that are blocked while a (non-VM) thread is
a61af66fc99e Initial load
duke
parents:
diff changeset
533 // running Java. Only the VM thread handles these signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
534 sigset_t* os::Linux::vm_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
536 return &vm_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
538
a61af66fc99e Initial load
duke
parents:
diff changeset
539 // These are signals that are blocked during cond_wait to allow debugger in
a61af66fc99e Initial load
duke
parents:
diff changeset
540 sigset_t* os::Linux::allowdebug_blocked_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
542 return &allowdebug_blocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
544
a61af66fc99e Initial load
duke
parents:
diff changeset
545 void os::Linux::hotspot_sigmask(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547 //Save caller's signal mask before setting VM signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
548 sigset_t caller_sigmask;
a61af66fc99e Initial load
duke
parents:
diff changeset
549 pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask);
a61af66fc99e Initial load
duke
parents:
diff changeset
550
a61af66fc99e Initial load
duke
parents:
diff changeset
551 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
552 osthread->set_caller_sigmask(caller_sigmask);
a61af66fc99e Initial load
duke
parents:
diff changeset
553
a61af66fc99e Initial load
duke
parents:
diff changeset
554 pthread_sigmask(SIG_UNBLOCK, os::Linux::unblocked_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
555
a61af66fc99e Initial load
duke
parents:
diff changeset
556 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
557 if (thread->is_VM_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // Only the VM thread handles BREAK_SIGNAL ...
a61af66fc99e Initial load
duke
parents:
diff changeset
559 pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
560 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // ... all other threads block BREAK_SIGNAL
a61af66fc99e Initial load
duke
parents:
diff changeset
562 pthread_sigmask(SIG_BLOCK, vm_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
565 }
a61af66fc99e Initial load
duke
parents:
diff changeset
566
a61af66fc99e Initial load
duke
parents:
diff changeset
567 //////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
568 // detecting pthread library
a61af66fc99e Initial load
duke
parents:
diff changeset
569
a61af66fc99e Initial load
duke
parents:
diff changeset
570 void os::Linux::libpthread_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // Save glibc and pthread version strings. Note that _CS_GNU_LIBC_VERSION
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // and _CS_GNU_LIBPTHREAD_VERSION are supported in glibc >= 2.3.2. Use a
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // generic name for earlier versions.
a61af66fc99e Initial load
duke
parents:
diff changeset
574 // Define macros here so we can build HotSpot on old systems.
a61af66fc99e Initial load
duke
parents:
diff changeset
575 # ifndef _CS_GNU_LIBC_VERSION
a61af66fc99e Initial load
duke
parents:
diff changeset
576 # define _CS_GNU_LIBC_VERSION 2
a61af66fc99e Initial load
duke
parents:
diff changeset
577 # endif
a61af66fc99e Initial load
duke
parents:
diff changeset
578 # ifndef _CS_GNU_LIBPTHREAD_VERSION
a61af66fc99e Initial load
duke
parents:
diff changeset
579 # define _CS_GNU_LIBPTHREAD_VERSION 3
a61af66fc99e Initial load
duke
parents:
diff changeset
580 # endif
a61af66fc99e Initial load
duke
parents:
diff changeset
581
a61af66fc99e Initial load
duke
parents:
diff changeset
582 size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
583 if (n > 0) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
584 char *str = (char *)malloc(n, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
585 confstr(_CS_GNU_LIBC_VERSION, str, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
586 os::Linux::set_glibc_version(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
587 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // _CS_GNU_LIBC_VERSION is not supported, try gnu_get_libc_version()
a61af66fc99e Initial load
duke
parents:
diff changeset
589 static char _gnu_libc_version[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
590 jio_snprintf(_gnu_libc_version, sizeof(_gnu_libc_version),
a61af66fc99e Initial load
duke
parents:
diff changeset
591 "glibc %s %s", gnu_get_libc_version(), gnu_get_libc_release());
a61af66fc99e Initial load
duke
parents:
diff changeset
592 os::Linux::set_glibc_version(_gnu_libc_version);
a61af66fc99e Initial load
duke
parents:
diff changeset
593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
594
a61af66fc99e Initial load
duke
parents:
diff changeset
595 n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 if (n > 0) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
597 char *str = (char *)malloc(n, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
598 confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
599 // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
a61af66fc99e Initial load
duke
parents:
diff changeset
600 // us "NPTL-0.29" even we are running with LinuxThreads. Check if this
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
601 // is the case. LinuxThreads has a hard limit on max number of threads.
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
602 // So sysconf(_SC_THREAD_THREADS_MAX) will return a positive value.
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
603 // On the other hand, NPTL does not have such a limit, sysconf()
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
604 // will return -1 and errno is not changed. Check if it is really NPTL.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
605 if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 &&
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
606 strstr(str, "NPTL") &&
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
607 sysconf(_SC_THREAD_THREADS_MAX) > 0) {
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
608 free(str);
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
609 os::Linux::set_libpthread_version("linuxthreads");
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
610 } else {
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
611 os::Linux::set_libpthread_version(str);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
613 } else {
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
614 // glibc before 2.3.2 only has LinuxThreads.
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
615 os::Linux::set_libpthread_version("linuxthreads");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
617
a61af66fc99e Initial load
duke
parents:
diff changeset
618 if (strstr(libpthread_version(), "NPTL")) {
a61af66fc99e Initial load
duke
parents:
diff changeset
619 os::Linux::set_is_NPTL();
a61af66fc99e Initial load
duke
parents:
diff changeset
620 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
621 os::Linux::set_is_LinuxThreads();
a61af66fc99e Initial load
duke
parents:
diff changeset
622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // LinuxThreads have two flavors: floating-stack mode, which allows variable
a61af66fc99e Initial load
duke
parents:
diff changeset
625 // stack size; and fixed-stack mode. NPTL is always floating-stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
626 if (os::Linux::is_NPTL() || os::Linux::supports_variable_stack_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
627 os::Linux::set_is_floating_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
630
a61af66fc99e Initial load
duke
parents:
diff changeset
631 /////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // thread stack
a61af66fc99e Initial load
duke
parents:
diff changeset
633
a61af66fc99e Initial load
duke
parents:
diff changeset
634 // Force Linux kernel to expand current thread stack. If "bottom" is close
a61af66fc99e Initial load
duke
parents:
diff changeset
635 // to the stack guard, caller should block all signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
636 //
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // MAP_GROWSDOWN:
a61af66fc99e Initial load
duke
parents:
diff changeset
638 // A special mmap() flag that is used to implement thread stacks. It tells
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // kernel that the memory region should extend downwards when needed. This
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // allows early versions of LinuxThreads to only mmap the first few pages
a61af66fc99e Initial load
duke
parents:
diff changeset
641 // when creating a new thread. Linux kernel will automatically expand thread
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // stack as needed (on page faults).
a61af66fc99e Initial load
duke
parents:
diff changeset
643 //
a61af66fc99e Initial load
duke
parents:
diff changeset
644 // However, because the memory region of a MAP_GROWSDOWN stack can grow on
a61af66fc99e Initial load
duke
parents:
diff changeset
645 // demand, if a page fault happens outside an already mapped MAP_GROWSDOWN
a61af66fc99e Initial load
duke
parents:
diff changeset
646 // region, it's hard to tell if the fault is due to a legitimate stack
a61af66fc99e Initial load
duke
parents:
diff changeset
647 // access or because of reading/writing non-exist memory (e.g. buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // overrun). As a rule, if the fault happens below current stack pointer,
a61af66fc99e Initial load
duke
parents:
diff changeset
649 // Linux kernel does not expand stack, instead a SIGSEGV is sent to the
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // application (see Linux kernel fault.c).
a61af66fc99e Initial load
duke
parents:
diff changeset
651 //
a61af66fc99e Initial load
duke
parents:
diff changeset
652 // This Linux feature can cause SIGSEGV when VM bangs thread stack for
a61af66fc99e Initial load
duke
parents:
diff changeset
653 // stack overflow detection.
a61af66fc99e Initial load
duke
parents:
diff changeset
654 //
a61af66fc99e Initial load
duke
parents:
diff changeset
655 // Newer version of LinuxThreads (since glibc-2.2, or, RH-7.x) and NPTL do
a61af66fc99e Initial load
duke
parents:
diff changeset
656 // not use this flag. However, the stack of initial thread is not created
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // by pthread, it is still MAP_GROWSDOWN. Also it's possible (though
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // unlikely) that user code can create a thread with MAP_GROWSDOWN stack
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // and then attach the thread to JVM.
a61af66fc99e Initial load
duke
parents:
diff changeset
660 //
a61af66fc99e Initial load
duke
parents:
diff changeset
661 // To get around the problem and allow stack banging on Linux, we need to
a61af66fc99e Initial load
duke
parents:
diff changeset
662 // manually expand thread stack after receiving the SIGSEGV.
a61af66fc99e Initial load
duke
parents:
diff changeset
663 //
a61af66fc99e Initial load
duke
parents:
diff changeset
664 // There are two ways to expand thread stack to address "bottom", we used
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // both of them in JVM before 1.5:
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // 1. adjust stack pointer first so that it is below "bottom", and then
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // touch "bottom"
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // 2. mmap() the page in question
a61af66fc99e Initial load
duke
parents:
diff changeset
669 //
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // Now alternate signal stack is gone, it's harder to use 2. For instance,
a61af66fc99e Initial load
duke
parents:
diff changeset
671 // if current sp is already near the lower end of page 101, and we need to
a61af66fc99e Initial load
duke
parents:
diff changeset
672 // call mmap() to map page 100, it is possible that part of the mmap() frame
a61af66fc99e Initial load
duke
parents:
diff changeset
673 // will be placed in page 100. When page 100 is mapped, it is zero-filled.
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // That will destroy the mmap() frame and cause VM to crash.
a61af66fc99e Initial load
duke
parents:
diff changeset
675 //
a61af66fc99e Initial load
duke
parents:
diff changeset
676 // The following code works by adjusting sp first, then accessing the "bottom"
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // page to force a page fault. Linux kernel will then automatically expand the
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // stack mapping.
a61af66fc99e Initial load
duke
parents:
diff changeset
679 //
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // _expand_stack_to() assumes its frame size is less than page size, which
a61af66fc99e Initial load
duke
parents:
diff changeset
681 // should always be true if the function is not inlined.
a61af66fc99e Initial load
duke
parents:
diff changeset
682
a61af66fc99e Initial load
duke
parents:
diff changeset
683 #if __GNUC__ < 3 // gcc 2.x does not support noinline attribute
a61af66fc99e Initial load
duke
parents:
diff changeset
684 #define NOINLINE
a61af66fc99e Initial load
duke
parents:
diff changeset
685 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
686 #define NOINLINE __attribute__ ((noinline))
a61af66fc99e Initial load
duke
parents:
diff changeset
687 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 static void _expand_stack_to(address bottom) NOINLINE;
a61af66fc99e Initial load
duke
parents:
diff changeset
690
a61af66fc99e Initial load
duke
parents:
diff changeset
691 static void _expand_stack_to(address bottom) {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 address sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
693 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
694 volatile char *p;
a61af66fc99e Initial load
duke
parents:
diff changeset
695
a61af66fc99e Initial load
duke
parents:
diff changeset
696 // Adjust bottom to point to the largest address within the same page, it
a61af66fc99e Initial load
duke
parents:
diff changeset
697 // gives us a one-page buffer if alloca() allocates slightly more memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
698 bottom = (address)align_size_down((uintptr_t)bottom, os::Linux::page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
699 bottom += os::Linux::page_size() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
700
a61af66fc99e Initial load
duke
parents:
diff changeset
701 // sp might be slightly above current stack pointer; if that's the case, we
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // will alloca() a little more space than necessary, which is OK. Don't use
a61af66fc99e Initial load
duke
parents:
diff changeset
703 // os::current_stack_pointer(), as its result can be slightly below current
a61af66fc99e Initial load
duke
parents:
diff changeset
704 // stack pointer, causing us to not alloca enough to reach "bottom".
a61af66fc99e Initial load
duke
parents:
diff changeset
705 sp = (address)&sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
706
a61af66fc99e Initial load
duke
parents:
diff changeset
707 if (sp > bottom) {
a61af66fc99e Initial load
duke
parents:
diff changeset
708 size = sp - bottom;
a61af66fc99e Initial load
duke
parents:
diff changeset
709 p = (volatile char *)alloca(size);
a61af66fc99e Initial load
duke
parents:
diff changeset
710 assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?");
a61af66fc99e Initial load
duke
parents:
diff changeset
711 p[0] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
714
a61af66fc99e Initial load
duke
parents:
diff changeset
715 bool os::Linux::manually_expand_stack(JavaThread * t, address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
716 assert(t!=NULL, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
717 assert(t->osthread()->expanding_stack(), "expand should be set");
a61af66fc99e Initial load
duke
parents:
diff changeset
718 assert(t->stack_base() != NULL, "stack_base was not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if (addr < t->stack_base() && addr >= t->stack_yellow_zone_base()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
721 sigset_t mask_all, old_sigset;
a61af66fc99e Initial load
duke
parents:
diff changeset
722 sigfillset(&mask_all);
a61af66fc99e Initial load
duke
parents:
diff changeset
723 pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset);
a61af66fc99e Initial load
duke
parents:
diff changeset
724 _expand_stack_to(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
725 pthread_sigmask(SIG_SETMASK, &old_sigset, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
726 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
728 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
730
a61af66fc99e Initial load
duke
parents:
diff changeset
731 //////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // create new thread
a61af66fc99e Initial load
duke
parents:
diff changeset
733
a61af66fc99e Initial load
duke
parents:
diff changeset
734 static address highest_vm_reserved_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
735
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // check if it's safe to start a new thread
a61af66fc99e Initial load
duke
parents:
diff changeset
737 static bool _thread_safety_check(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
738 if (os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // Fixed stack LinuxThreads (SuSE Linux/x86, and some versions of Redhat)
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // Heap is mmap'ed at lower end of memory space. Thread stacks are
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // allocated (MAP_FIXED) from high address space. Every thread stack
a61af66fc99e Initial load
duke
parents:
diff changeset
742 // occupies a fixed size slot (usually 2Mbytes, but user can change
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // it to other values if they rebuild LinuxThreads).
a61af66fc99e Initial load
duke
parents:
diff changeset
744 //
a61af66fc99e Initial load
duke
parents:
diff changeset
745 // Problem with MAP_FIXED is that mmap() can still succeed even part of
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // the memory region has already been mmap'ed. That means if we have too
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // many threads and/or very large heap, eventually thread stack will
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // collide with heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
749 //
a61af66fc99e Initial load
duke
parents:
diff changeset
750 // Here we try to prevent heap/stack collision by comparing current
a61af66fc99e Initial load
duke
parents:
diff changeset
751 // stack bottom with the highest address that has been mmap'ed by JVM
a61af66fc99e Initial load
duke
parents:
diff changeset
752 // plus a safety margin for memory maps created by native code.
a61af66fc99e Initial load
duke
parents:
diff changeset
753 //
a61af66fc99e Initial load
duke
parents:
diff changeset
754 // This feature can be disabled by setting ThreadSafetyMargin to 0
a61af66fc99e Initial load
duke
parents:
diff changeset
755 //
a61af66fc99e Initial load
duke
parents:
diff changeset
756 if (ThreadSafetyMargin > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
757 address stack_bottom = os::current_stack_base() - os::current_stack_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
758
a61af66fc99e Initial load
duke
parents:
diff changeset
759 // not safe if our stack extends below the safety margin
a61af66fc99e Initial load
duke
parents:
diff changeset
760 return stack_bottom - ThreadSafetyMargin >= highest_vm_reserved_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
761 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
762 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
764 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
765 // Floating stack LinuxThreads or NPTL:
a61af66fc99e Initial load
duke
parents:
diff changeset
766 // Unlike fixed stack LinuxThreads, thread stacks are not MAP_FIXED. When
a61af66fc99e Initial load
duke
parents:
diff changeset
767 // there's not enough space left, pthread_create() will fail. If we come
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // here, that means enough space has been reserved for stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
769 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
770 }
a61af66fc99e Initial load
duke
parents:
diff changeset
771 }
a61af66fc99e Initial load
duke
parents:
diff changeset
772
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // Thread start routine for all newly created threads
a61af66fc99e Initial load
duke
parents:
diff changeset
774 static void *java_start(Thread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
775 // Try to randomize the cache line index of hot stack frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // This helps when threads of the same stack traces evict each other's
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // cache lines. The threads can be either from the same JVM instance, or
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // from different JVM instances. The benefit is especially true for
a61af66fc99e Initial load
duke
parents:
diff changeset
779 // processors with hyperthreading technology.
a61af66fc99e Initial load
duke
parents:
diff changeset
780 static int counter = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
781 int pid = os::current_process_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
782 alloca(((pid ^ counter++) & 7) * 128);
a61af66fc99e Initial load
duke
parents:
diff changeset
783
a61af66fc99e Initial load
duke
parents:
diff changeset
784 ThreadLocalStorage::set_thread(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
785
a61af66fc99e Initial load
duke
parents:
diff changeset
786 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
787 Monitor* sync = osthread->startThread_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
788
a61af66fc99e Initial load
duke
parents:
diff changeset
789 // non floating stack LinuxThreads needs extra check, see above
a61af66fc99e Initial load
duke
parents:
diff changeset
790 if (!_thread_safety_check(thread)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // notify parent thread
a61af66fc99e Initial load
duke
parents:
diff changeset
792 MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
793 osthread->set_state(ZOMBIE);
a61af66fc99e Initial load
duke
parents:
diff changeset
794 sync->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
795 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
796 }
a61af66fc99e Initial load
duke
parents:
diff changeset
797
a61af66fc99e Initial load
duke
parents:
diff changeset
798 // thread_id is kernel thread id (similar to Solaris LWP id)
a61af66fc99e Initial load
duke
parents:
diff changeset
799 osthread->set_thread_id(os::Linux::gettid());
a61af66fc99e Initial load
duke
parents:
diff changeset
800
a61af66fc99e Initial load
duke
parents:
diff changeset
801 if (UseNUMA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
802 int lgrp_id = os::numa_get_group_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
803 if (lgrp_id != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
804 thread->set_lgrp_id(lgrp_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
805 }
a61af66fc99e Initial load
duke
parents:
diff changeset
806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
807 // initialize signal mask for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
808 os::Linux::hotspot_sigmask(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
809
a61af66fc99e Initial load
duke
parents:
diff changeset
810 // initialize floating point control register
a61af66fc99e Initial load
duke
parents:
diff changeset
811 os::Linux::init_thread_fpu_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
812
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // handshaking with parent thread
a61af66fc99e Initial load
duke
parents:
diff changeset
814 {
a61af66fc99e Initial load
duke
parents:
diff changeset
815 MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
816
a61af66fc99e Initial load
duke
parents:
diff changeset
817 // notify parent thread
a61af66fc99e Initial load
duke
parents:
diff changeset
818 osthread->set_state(INITIALIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
819 sync->notify_all();
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 // wait until os::start_thread()
a61af66fc99e Initial load
duke
parents:
diff changeset
822 while (osthread->get_state() == INITIALIZED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
823 sync->wait(Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
826
a61af66fc99e Initial load
duke
parents:
diff changeset
827 // call one more level start routine
a61af66fc99e Initial load
duke
parents:
diff changeset
828 thread->run();
a61af66fc99e Initial load
duke
parents:
diff changeset
829
a61af66fc99e Initial load
duke
parents:
diff changeset
830 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
832
a61af66fc99e Initial load
duke
parents:
diff changeset
833 bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
834 assert(thread->osthread() == NULL, "caller responsible");
a61af66fc99e Initial load
duke
parents:
diff changeset
835
a61af66fc99e Initial load
duke
parents:
diff changeset
836 // Allocate the OSThread object
a61af66fc99e Initial load
duke
parents:
diff changeset
837 OSThread* osthread = new OSThread(NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
838 if (osthread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
839 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
841
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // set the correct thread state
a61af66fc99e Initial load
duke
parents:
diff changeset
843 osthread->set_thread_type(thr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
844
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // Initial state is ALLOCATED but not INITIALIZED
a61af66fc99e Initial load
duke
parents:
diff changeset
846 osthread->set_state(ALLOCATED);
a61af66fc99e Initial load
duke
parents:
diff changeset
847
a61af66fc99e Initial load
duke
parents:
diff changeset
848 thread->set_osthread(osthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // init thread attributes
a61af66fc99e Initial load
duke
parents:
diff changeset
851 pthread_attr_t attr;
a61af66fc99e Initial load
duke
parents:
diff changeset
852 pthread_attr_init(&attr);
a61af66fc99e Initial load
duke
parents:
diff changeset
853 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
a61af66fc99e Initial load
duke
parents:
diff changeset
854
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // stack size
a61af66fc99e Initial load
duke
parents:
diff changeset
856 if (os::Linux::supports_variable_stack_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
857 // calculate stack size if it's not specified by caller
a61af66fc99e Initial load
duke
parents:
diff changeset
858 if (stack_size == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
859 stack_size = os::Linux::default_stack_size(thr_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 switch (thr_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
862 case os::java_thread:
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
863 // Java threads use ThreadStackSize which default value can be
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
864 // changed with the flag -Xss
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
865 assert (JavaThread::stack_size_at_create() > 0, "this should be set");
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
866 stack_size = JavaThread::stack_size_at_create();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
867 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
868 case os::compiler_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
869 if (CompilerThreadStackSize > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
870 stack_size = (size_t)(CompilerThreadStackSize * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
871 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
872 } // else fall through:
a61af66fc99e Initial load
duke
parents:
diff changeset
873 // use VMThreadStackSize if CompilerThreadStackSize is not defined
a61af66fc99e Initial load
duke
parents:
diff changeset
874 case os::vm_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
875 case os::pgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
876 case os::cgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
877 case os::watcher_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
878 if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
879 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
881 }
a61af66fc99e Initial load
duke
parents:
diff changeset
882
a61af66fc99e Initial load
duke
parents:
diff changeset
883 stack_size = MAX2(stack_size, os::Linux::min_stack_allowed);
a61af66fc99e Initial load
duke
parents:
diff changeset
884 pthread_attr_setstacksize(&attr, stack_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
885 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
886 // let pthread_create() pick the default value.
a61af66fc99e Initial load
duke
parents:
diff changeset
887 }
a61af66fc99e Initial load
duke
parents:
diff changeset
888
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // glibc guard page
a61af66fc99e Initial load
duke
parents:
diff changeset
890 pthread_attr_setguardsize(&attr, os::Linux::default_guard_size(thr_type));
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 ThreadState state;
a61af66fc99e Initial load
duke
parents:
diff changeset
893
a61af66fc99e Initial load
duke
parents:
diff changeset
894 {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // Serialize thread creation if we are running with fixed stack LinuxThreads
a61af66fc99e Initial load
duke
parents:
diff changeset
896 bool lock = os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
897 if (lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
898 os::Linux::createThread_lock()->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
900
a61af66fc99e Initial load
duke
parents:
diff changeset
901 pthread_t tid;
a61af66fc99e Initial load
duke
parents:
diff changeset
902 int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
903
a61af66fc99e Initial load
duke
parents:
diff changeset
904 pthread_attr_destroy(&attr);
a61af66fc99e Initial load
duke
parents:
diff changeset
905
a61af66fc99e Initial load
duke
parents:
diff changeset
906 if (ret != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
907 if (PrintMiscellaneous && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
908 perror("pthread_create()");
a61af66fc99e Initial load
duke
parents:
diff changeset
909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // Need to clean up stuff we've allocated so far
a61af66fc99e Initial load
duke
parents:
diff changeset
911 thread->set_osthread(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
912 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
913 if (lock) os::Linux::createThread_lock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
914 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
916
a61af66fc99e Initial load
duke
parents:
diff changeset
917 // Store pthread info into the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
918 osthread->set_pthread_id(tid);
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 // Wait until child thread is either initialized or aborted
a61af66fc99e Initial load
duke
parents:
diff changeset
921 {
a61af66fc99e Initial load
duke
parents:
diff changeset
922 Monitor* sync_with_child = osthread->startThread_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
923 MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
924 while ((state = osthread->get_state()) == ALLOCATED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
925 sync_with_child->wait(Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
928
a61af66fc99e Initial load
duke
parents:
diff changeset
929 if (lock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
930 os::Linux::createThread_lock()->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // Aborted due to thread limit being reached
a61af66fc99e Initial load
duke
parents:
diff changeset
935 if (state == ZOMBIE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
936 thread->set_osthread(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
937 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
938 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940
a61af66fc99e Initial load
duke
parents:
diff changeset
941 // The thread is returned suspended (in state INITIALIZED),
a61af66fc99e Initial load
duke
parents:
diff changeset
942 // and is started higher up in the call chain
a61af66fc99e Initial load
duke
parents:
diff changeset
943 assert(state == INITIALIZED, "race condition");
a61af66fc99e Initial load
duke
parents:
diff changeset
944 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 /////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
948 // attach existing thread
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // bootstrap the main thread
a61af66fc99e Initial load
duke
parents:
diff changeset
951 bool os::create_main_thread(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
952 assert(os::Linux::_main_thread == pthread_self(), "should be called inside main thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
953 return create_attached_thread(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
955
a61af66fc99e Initial load
duke
parents:
diff changeset
956 bool os::create_attached_thread(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
957 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
958 thread->verify_not_published();
a61af66fc99e Initial load
duke
parents:
diff changeset
959 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
960
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // Allocate the OSThread object
a61af66fc99e Initial load
duke
parents:
diff changeset
962 OSThread* osthread = new OSThread(NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
963
a61af66fc99e Initial load
duke
parents:
diff changeset
964 if (osthread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
965 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // Store pthread info into the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
969 osthread->set_thread_id(os::Linux::gettid());
a61af66fc99e Initial load
duke
parents:
diff changeset
970 osthread->set_pthread_id(::pthread_self());
a61af66fc99e Initial load
duke
parents:
diff changeset
971
a61af66fc99e Initial load
duke
parents:
diff changeset
972 // initialize floating point control register
a61af66fc99e Initial load
duke
parents:
diff changeset
973 os::Linux::init_thread_fpu_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
974
a61af66fc99e Initial load
duke
parents:
diff changeset
975 // Initial thread state is RUNNABLE
a61af66fc99e Initial load
duke
parents:
diff changeset
976 osthread->set_state(RUNNABLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978 thread->set_osthread(osthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
979
a61af66fc99e Initial load
duke
parents:
diff changeset
980 if (UseNUMA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
981 int lgrp_id = os::numa_get_group_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
982 if (lgrp_id != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
983 thread->set_lgrp_id(lgrp_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
986
a61af66fc99e Initial load
duke
parents:
diff changeset
987 if (os::Linux::is_initial_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // If current thread is initial thread, its stack is mapped on demand,
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // see notes about MAP_GROWSDOWN. Here we try to force kernel to map
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // the entire stack region to avoid SEGV in stack banging.
a61af66fc99e Initial load
duke
parents:
diff changeset
991 // It is also useful to get around the heap-stack-gap problem on SuSE
a61af66fc99e Initial load
duke
parents:
diff changeset
992 // kernel (see 4821821 for details). We first expand stack to the top
a61af66fc99e Initial load
duke
parents:
diff changeset
993 // of yellow zone, then enable stack yellow zone (order is significant,
a61af66fc99e Initial load
duke
parents:
diff changeset
994 // enabling yellow zone first will crash JVM on SuSE Linux), so there
a61af66fc99e Initial load
duke
parents:
diff changeset
995 // is no gap between the last two virtual memory regions.
a61af66fc99e Initial load
duke
parents:
diff changeset
996
a61af66fc99e Initial load
duke
parents:
diff changeset
997 JavaThread *jt = (JavaThread *)thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
998 address addr = jt->stack_yellow_zone_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
999 assert(addr != NULL, "initialization problem?");
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 assert(jt->stack_available(addr) > 0, "stack guard should not be enabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
1001
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 osthread->set_expanding_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 os::Linux::manually_expand_stack(jt, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 osthread->clear_expanding_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1006
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 // initialize signal mask for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 // and save the caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 os::Linux::hotspot_sigmask(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1010
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1013
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 void os::pd_start_thread(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 OSThread * osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 assert(osthread->get_state() != INITIALIZED, "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 Monitor* sync_with_child = osthread->startThread_lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 MutexLockerEx ml(sync_with_child, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 sync_with_child->notify();
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1021
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 // Free Linux resources related to the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 void os::free_thread(OSThread* osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 assert(osthread != NULL, "osthread not set");
a61af66fc99e Initial load
duke
parents:
diff changeset
1025
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 if (Thread::current()->osthread() == osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 // Restore caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 sigset_t sigmask = osthread->caller_sigmask();
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 pthread_sigmask(SIG_SETMASK, &sigmask, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1031
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1034
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 //////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 // thread local storage
a61af66fc99e Initial load
duke
parents:
diff changeset
1037
17845
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1038 // Restore the thread pointer if the destructor is called. This is in case
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1039 // someone from JNI code sets up a destructor with pthread_key_create to run
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1040 // detachCurrentThread on thread death. Unless we restore the thread pointer we
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1041 // will hang or crash. When detachCurrentThread is called the key will be set
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1042 // to null and we will not be called again. If detachCurrentThread is never
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1043 // called we could loop forever depending on the pthread implementation.
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1044 static void restore_thread_pointer(void* p) {
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1045 Thread* thread = (Thread*) p;
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1046 os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1047 }
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1048
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 int os::allocate_thread_local_storage() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 pthread_key_t key;
17845
21dd1c827123 8033696: "assert(thread != NULL) failed: just checking" due to Thread::current() and JNI pthread interaction
kevinw
parents: 17830
diff changeset
1051 int rslt = pthread_key_create(&key, restore_thread_pointer);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 assert(rslt == 0, "cannot allocate thread local storage");
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 return (int)key;
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1055
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 // Note: This is currently not used by VM, as we don't destroy TLS key
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // on VM exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 void os::free_thread_local_storage(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 int rslt = pthread_key_delete((pthread_key_t)index);
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 assert(rslt == 0, "invalid index");
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1062
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 void os::thread_local_storage_at_put(int index, void* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 int rslt = pthread_setspecific((pthread_key_t)index, value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 assert(rslt == 0, "pthread_setspecific failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 extern "C" Thread* get_thread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 return ThreadLocalStorage::thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1071
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 //////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 // initial thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1074
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // Check if current thread is the initial thread, similar to Solaris thr_main.
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 bool os::Linux::is_initial_thread(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 char dummy;
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // If called before init complete, thread stack bottom will be null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // Can be called if fatal error occurs before initialization.
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 if (initial_thread_stack_bottom() == NULL) return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 assert(initial_thread_stack_bottom() != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 initial_thread_stack_size() != 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 "os::init did not locate initial thread's stack region");
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 if ((address)&dummy >= initial_thread_stack_bottom() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 (address)&dummy < initial_thread_stack_bottom() + initial_thread_stack_size())
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 else return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1089
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 // Find the virtual memory area that contains addr
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 static bool find_vma(address addr, address* vma_low, address* vma_high) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 FILE *fp = fopen("/proc/self/maps", "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 if (fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 address low, high;
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 while (!feof(fp)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 if (fscanf(fp, "%p-%p", &low, &high) == 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 if (low <= addr && addr < high) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 if (vma_low) *vma_low = low;
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 if (vma_high) *vma_high = high;
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 fclose (fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 int ch = fgetc(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 if (ch == EOF || ch == (int)'\n') break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1113
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 // Locate initial thread stack. This special handling of initial thread stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 // is needed because pthread_getattr_np() on most (all?) Linux distros returns
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 // bogus value for initial thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 void os::Linux::capture_initial_stack(size_t max_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 // stack size is the easy part, get it from RLIMIT_STACK
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 size_t stack_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 struct rlimit rlim;
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 getrlimit(RLIMIT_STACK, &rlim);
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 stack_size = rlim.rlim_cur;
a61af66fc99e Initial load
duke
parents:
diff changeset
1123
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 // 6308388: a bug in ld.so will relocate its own .data section to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 // lower end of primordial stack; reduce ulimit -s value a little bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // so we won't install guard page on ld.so's data section.
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 stack_size -= 2 * page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1128
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 // 4441425: avoid crash with "unlimited" stack size on SuSE 7.1 or Redhat
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 // 7.1, in both cases we will get 2G in return value.
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // 4466587: glibc 2.2.x compiled w/o "--enable-kernel=2.4.0" (RH 7.0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 // SuSE 7.2, Debian) can not handle alternate signal stack correctly
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 // for initial thread if its stack size exceeds 6M. Cap it at 2M,
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // in case other parts in glibc still assumes 2M max stack size.
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // FIXME: alt signal stack is gone, maybe we can relax this constraint?
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // Problem still exists RH7.2 (IA64 anyway) but 2MB is a little small
7994
9fae07c31641 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 7629
diff changeset
1137 if (stack_size > 2 * K * K IA64_ONLY(*2))
9fae07c31641 6518907: cleanup IA64 specific code in Hotspot
morris
parents: 7629
diff changeset
1138 stack_size = 2 * K * K IA64_ONLY(*2);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // Try to figure out where the stack base (top) is. This is harder.
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 // When an application is started, glibc saves the initial stack pointer in
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // a global variable "__libc_stack_end", which is then used by system
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // libraries. __libc_stack_end should be pretty close to stack top. The
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // variable is available since the very early days. However, because it is
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // a private interface, it could disappear in the future.
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 // Linux kernel saves start_stack information in /proc/<pid>/stat. Similar
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // to __libc_stack_end, it is very close to stack top, but isn't the real
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 // stack top. Note that /proc may not exist if VM is running as a chroot
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 // program, so reading /proc/<pid>/stat could fail. Also the contents of
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // /proc/<pid>/stat could change in the future (though unlikely).
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // We try __libc_stack_end first. If that doesn't work, look for
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // /proc/<pid>/stat. If neither of them works, we use current stack pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 // as a hint, which should work well in most cases.
a61af66fc99e Initial load
duke
parents:
diff changeset
1156
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 uintptr_t stack_start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1158
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 // try __libc_stack_end first
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 uintptr_t *p = (uintptr_t *)dlsym(RTLD_DEFAULT, "__libc_stack_end");
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 if (p && *p) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 stack_start = *p;
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 // see if we can get the start_stack field from /proc/self/stat
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 FILE *fp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 int pid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 char state;
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 int ppid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 int pgrp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 int session;
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 int nr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 int tpgrp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 unsigned long flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 unsigned long minflt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 unsigned long cminflt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 unsigned long majflt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 unsigned long cmajflt;
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 unsigned long utime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 unsigned long stime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 long cutime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 long cstime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 long prio;
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 long nice;
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 long junk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 long it_real;
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 uintptr_t start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 uintptr_t vsize;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1188 intptr_t rss;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1189 uintptr_t rsslim;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 uintptr_t scodes;
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 uintptr_t ecode;
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1193
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // Figure what the primordial thread stack base is. Code is inspired
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // by email from Hans Boehm. /proc/self/stat begins with current pid,
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // followed by command name surrounded by parentheses, state, etc.
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 char stat[2048];
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 int statlen;
a61af66fc99e Initial load
duke
parents:
diff changeset
1199
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 fp = fopen("/proc/self/stat", "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 if (fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 statlen = fread(stat, 1, 2047, fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 stat[statlen] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1205
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // Skip pid and the command string. Note that we could be dealing with
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 // weird command names, e.g. user could decide to rename java launcher
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 // to "java 1.4.2 :)", then the stat file would look like
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 // 1234 (java 1.4.2 :)) R ... ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 // We don't really need to know the command string, just find the last
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 // occurrence of ")" and then start parsing from there. See bug 4726580.
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 char * s = strrchr(stat, ')');
a61af66fc99e Initial load
duke
parents:
diff changeset
1213
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 if (s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 // Skip blank chars
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 do s++; while (isspace(*s));
a61af66fc99e Initial load
duke
parents:
diff changeset
1218
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1219 #define _UFM UINTX_FORMAT
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1220 #define _DFM INTX_FORMAT
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1221
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1222 /* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1223 /* 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1224 i = sscanf(s, "%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu %ld %ld %ld %ld %ld %ld " _UFM _UFM _DFM _UFM _UFM _UFM _UFM,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 &state, /* 3 %c */
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 &ppid, /* 4 %d */
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 &pgrp, /* 5 %d */
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 &session, /* 6 %d */
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 &nr, /* 7 %d */
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 &tpgrp, /* 8 %d */
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 &flags, /* 9 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 &minflt, /* 10 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 &cminflt, /* 11 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 &majflt, /* 12 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 &cmajflt, /* 13 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 &utime, /* 14 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 &stime, /* 15 %lu */
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 &cutime, /* 16 %ld */
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 &cstime, /* 17 %ld */
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 &prio, /* 18 %ld */
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 &nice, /* 19 %ld */
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 &junk, /* 20 %ld */
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 &it_real, /* 21 %ld */
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1244 &start, /* 22 UINTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1245 &vsize, /* 23 UINTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1246 &rss, /* 24 INTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1247 &rsslim, /* 25 UINTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1248 &scodes, /* 26 UINTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1249 &ecode, /* 27 UINTX_FORMAT */
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1250 &stack_start); /* 28 UINTX_FORMAT */
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1252
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1253 #undef _UFM
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1254 #undef _DFM
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1255
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 if (i != 28 - 2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 assert(false, "Bad conversion from /proc/self/stat");
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 // product mode - assume we are the initial thread, good luck in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // embedded case.
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 warning("Can't detect initial thread stack location - bad conversion");
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 stack_start = (uintptr_t) &rlim;
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 // For some reason we can't open /proc/self/stat (for example, running on
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 // FreeBSD with a Linux emulator, or inside chroot), this should work for
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 // most cases, so don't abort:
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 warning("Can't detect initial thread stack location - no /proc/self/stat");
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 stack_start = (uintptr_t) &rlim;
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1271
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 // Now we have a pointer (stack_start) very close to the stack top, the
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // next thing to do is to figure out the exact location of stack top. We
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // can find out the virtual memory area that contains stack_start by
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // reading /proc/self/maps, it should be the last vma in /proc/self/maps,
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // and its upper limit is the real stack top. (again, this would fail if
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // running inside chroot, because /proc may not exist.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1278
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 uintptr_t stack_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 address low, high;
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 if (find_vma((address)stack_start, &low, &high)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // success, "high" is the true stack top. (ignore "low", because initial
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // thread stack grows on demand, its real bottom is high - RLIMIT_STACK.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 stack_top = (uintptr_t)high;
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // failed, likely because /proc/self/maps does not exist
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 warning("Can't detect initial thread stack location - find_vma failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // best effort: stack_start is normally within a few pages below the real
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 // stack top, use it as stack top, and reduce stack size so we won't put
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 // guard page outside stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 stack_top = stack_start;
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 stack_size -= 16 * page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1294
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // stack_top could be partially down the page so align it
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 stack_top = align_size_up(stack_top, page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1297
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 if (max_size && stack_size > max_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 _initial_thread_stack_size = max_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 _initial_thread_stack_size = stack_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1303
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 _initial_thread_stack_size = align_size_down(_initial_thread_stack_size, page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 _initial_thread_stack_bottom = (address)stack_top - _initial_thread_stack_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1307
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 // time support
a61af66fc99e Initial load
duke
parents:
diff changeset
1310
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // Time since start-up in seconds to a fine granularity.
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // Used by VMSelfDestructTimer and the MemProfiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 double os::elapsedTime() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1314
12997
e4f478e7781b 8027294: Prepare hotspot for non TOD based uptime counter
jbachorik
parents: 12840
diff changeset
1315 return ((double)os::elapsed_counter()) / os::elapsed_frequency(); // nanosecond resolution
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1317
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 jlong os::elapsed_counter() {
12997
e4f478e7781b 8027294: Prepare hotspot for non TOD based uptime counter
jbachorik
parents: 12840
diff changeset
1319 return javaTimeNanos() - initial_time_count;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1321
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 jlong os::elapsed_frequency() {
12997
e4f478e7781b 8027294: Prepare hotspot for non TOD based uptime counter
jbachorik
parents: 12840
diff changeset
1323 return NANOSECS_PER_SEC; // nanosecond resolution
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1325
10372
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
1326 bool os::supports_vtime() { return true; }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1327 bool os::enable_vtime() { return false; }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1328 bool os::vtime_enabled() { return false; }
10372
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
1329
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1330 double os::elapsedVTime() {
10372
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
1331 struct rusage usage;
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
1332 int retval = getrusage(RUSAGE_THREAD, &usage);
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
1333 if (retval == 0) {
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
1334 return (double) (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) + (double) (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000 * 1000);
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
1335 } else {
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
1336 // better than nothing, but not much
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
1337 return elapsedTime();
e72f7eecc96d 8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents: 10208
diff changeset
1338 }
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1339 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 141
diff changeset
1340
61
5a76ab815e34 6667833: Remove CacheTimeMillis
sbohne
parents: 0
diff changeset
1341 jlong os::javaTimeMillis() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 timeval time;
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 int status = gettimeofday(&time, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 assert(status != -1, "linux error");
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1347
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 #ifndef CLOCK_MONOTONIC
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 #define CLOCK_MONOTONIC (1)
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1351
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 void os::Linux::clock_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 // we do dlopen's in this particular order due to bug in linux
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 // dynamical loader (see 6348968) leading to crash on exit
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 void* handle = dlopen("librt.so.1", RTLD_LAZY);
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 if (handle == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 handle = dlopen("librt.so", RTLD_LAZY);
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1359
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 if (handle) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 int (*clock_getres_func)(clockid_t, struct timespec*) =
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres");
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 int (*clock_gettime_func)(clockid_t, struct timespec*) =
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 (int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_gettime");
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 if (clock_getres_func && clock_gettime_func) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 // See if monotonic clock is supported by the kernel. Note that some
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 // early implementations simply return kernel jiffies (updated every
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 // 1/100 or 1/1000 second). It would be bad to use such a low res clock
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 // for nano time (though the monotonic property is still nice to have).
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 // It's fixed in newer kernels, however clock_getres() still returns
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // 1/HZ. We check if clock_getres() works, but will ignore its reported
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 // resolution for now. Hopefully as people move to new kernels, this
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 // won't be a problem.
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 struct timespec res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 struct timespec tp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 if (clock_getres_func (CLOCK_MONOTONIC, &res) == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 // yes, monotonic clock is supported
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 _clock_gettime = clock_gettime_func;
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
1380 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 // close librt if there is no monotonic clock
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 dlclose(handle);
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 }
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
1387 warning("No monotonic clock was available - timed services may " \
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
1388 "be adversely affected if the time-of-day clock changes");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1390
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 #ifndef SYS_clock_getres
a61af66fc99e Initial load
duke
parents:
diff changeset
1392
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 #if defined(IA32) || defined(AMD64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 #define SYS_clock_getres IA32_ONLY(266) AMD64_ONLY(229)
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1395 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 #else
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1397 #warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time"
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1398 #define sys_clock_getres(x,y) -1
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1400
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1401 #else
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
1402 #define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1404
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 void os::Linux::fast_thread_clock_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 if (!UseLinuxPosixThreadCPUClocks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 clockid_t clockid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 struct timespec tp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 int (*pthread_getcpuclockid_func)(pthread_t, clockid_t *) =
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 (int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
a61af66fc99e Initial load
duke
parents:
diff changeset
1413
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 // Switch to using fast clocks for thread cpu time if
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // the sys_clock_getres() returns 0 error code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 // Note, that some kernels may support the current thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 // clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 // returned by the pthread_getcpuclockid().
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // If the fast Posix clocks are supported then the sys_clock_getres()
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 // must return at least tp.tv_sec == 0 which means a resolution
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // better than 1 sec. This is extra check for reliability.
a61af66fc99e Initial load
duke
parents:
diff changeset
1422
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 if(pthread_getcpuclockid_func &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 pthread_getcpuclockid_func(_main_thread, &clockid) == 0 &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 sys_clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1426
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 _supports_fast_thread_cpu_time = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 _pthread_getcpuclockid = pthread_getcpuclockid_func;
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1431
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 jlong os::javaTimeNanos() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 if (Linux::supports_monotonic_clock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 struct timespec tp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 int status = Linux::clock_gettime(CLOCK_MONOTONIC, &tp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 assert(status == 0, "gettime error");
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 timeval time;
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 int status = gettimeofday(&time, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 assert(status != -1, "linux error");
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 return 1000 * usecs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1447
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 if (Linux::supports_monotonic_clock()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 info_ptr->max_value = ALL_64_BITS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1451
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 info_ptr->may_skip_backward = false; // not subject to resetting or drifting
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 info_ptr->may_skip_forward = false; // not subject to resetting or drifting
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 // gettimeofday - based on time in seconds since the Epoch thus does not wrap
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 info_ptr->max_value = ALL_64_BITS;
a61af66fc99e Initial load
duke
parents:
diff changeset
1458
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // gettimeofday is a real time clock so it skips
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 info_ptr->may_skip_backward = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 info_ptr->may_skip_forward = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1463
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1466
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 // Return the real, user, and system times in seconds from an
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 // arbitrary fixed point in the past.
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 bool os::getTimesSecs(double* process_real_time,
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 double* process_user_time,
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 double* process_system_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 struct tms ticks;
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 clock_t real_ticks = times(&ticks);
a61af66fc99e Initial load
duke
parents:
diff changeset
1474
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 if (real_ticks == (clock_t) (-1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 double ticks_per_second = (double) clock_tics_per_sec;
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 *process_real_time = ((double) real_ticks) / ticks_per_second;
a61af66fc99e Initial load
duke
parents:
diff changeset
1482
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1486
a61af66fc99e Initial load
duke
parents:
diff changeset
1487
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 char * os::local_time_string(char *buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 struct tm t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 time_t long_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 time(&long_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 localtime_r(&long_time, &t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 t.tm_hour, t.tm_min, t.tm_sec);
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1498
548
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 516
diff changeset
1499 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 516
diff changeset
1500 return localtime_r(clock, res);
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 516
diff changeset
1501 }
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 516
diff changeset
1502
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 // runtime exit support
a61af66fc99e Initial load
duke
parents:
diff changeset
1505
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 // Note: os::shutdown() might be called very early during initialization, or
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 // called from signal handler. Before adding something to os::shutdown(), make
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 // sure it is async-safe and can handle partially initialized VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 void os::shutdown() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1510
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 // allow PerfMemory to attempt cleanup of any persistent resources
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 perfMemory_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1513
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 // needs to remove object in file system
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 AttachListener::abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
1516
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 // flush buffered output, finish log files
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 ostream_abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
1519
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 // Check for abort hook
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 abort_hook_t abort_hook = Arguments::abort_hook();
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 if (abort_hook != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 abort_hook();
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1525
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1527
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 // Note: os::abort() might be called very early during initialization, or
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 // called from signal handler. Before adding something to os::abort(), make
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 // sure it is async-safe and can handle partially initialized VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 void os::abort(bool dump_core) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 os::shutdown();
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 if (dump_core) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 fdStream out(defaultStream::output_fd());
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 out.print_raw("Current thread is ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 char buf[16];
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 out.print_raw_cr(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 out.print_raw_cr("Dumping core ...");
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 ::abort(); // dump core
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1544
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 ::exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1547
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 // Die immediately, no exit hook, no abort hook, no cleanup.
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 void os::die() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 // _exit() on LinuxThreads only kills current thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 ::abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1553
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1554
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1555 // This method is a copy of JDK's sysGetLastErrorString
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1556 // from src/solaris/hpi/src/system_md.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1557
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1558 size_t os::lasterror(char *buf, size_t len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1559
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1560 if (errno == 0) return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1561
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1562 const char *s = ::strerror(errno);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1563 size_t n = ::strlen(s);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1564 if (n >= len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1565 n = len - 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1566 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1567 ::strncpy(buf, s, n);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1568 buf[n] = '\0';
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1569 return n;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1570 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1571
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 intx os::current_thread_id() { return (intx)pthread_self(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 int os::current_process_id() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1574
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 // Under the old linux thread library, linux gives each thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 // its own process id. Because of this each thread will return
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 // a different pid if this method were to return the result
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 // of getpid(2). Linux provides no api that returns the pid
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 // of the launcher thread for the vm. This implementation
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 // returns a unique pid, the pid of the launcher thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 // that starts the vm 'process'.
a61af66fc99e Initial load
duke
parents:
diff changeset
1582
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 // Under the NPTL, getpid() returns the same pid as the
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 // launcher thread rather than a unique pid per thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 // Use gettid() if you want the old pre NPTL behaviour.
a61af66fc99e Initial load
duke
parents:
diff changeset
1586
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 // if you are looking for the result of a call to getpid() that
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 // returns a unique pid for the calling thread, then look at the
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 // OSThread::thread_id() method in osThread_linux.hpp file
a61af66fc99e Initial load
duke
parents:
diff changeset
1590
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 return (int)(_initial_pid ? _initial_pid : getpid());
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1593
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 // DLL functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1595
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 const char* os::dll_file_extension() { return ".so"; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1597
2130
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2033
diff changeset
1598 // This must be hard coded because it's the system's temporary
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2033
diff changeset
1599 // directory not the java application's temp directory, ala java.io.tmpdir.
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2033
diff changeset
1600 const char* os::get_temp_directory() { return "/tmp"; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1601
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1602 static bool file_exists(const char* filename) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1603 struct stat statbuf;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1604 if (filename == NULL || strlen(filename) == 0) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1605 return false;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1606 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1607 return os::stat(filename, &statbuf) == 0;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1608 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1609
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6825
diff changeset
1610 bool os::dll_build_name(char* buffer, size_t buflen,
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1611 const char* pname, const char* fname) {
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6825
diff changeset
1612 bool retval = false;
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1613 // Copied from libhpi
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1614 const size_t pnamelen = pname ? strlen(pname) : 0;
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1615
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6825
diff changeset
1616 // Return error on buffer overflow.
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1617 if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6825
diff changeset
1618 return retval;
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1619 }
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1620
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1621 if (pnamelen == 0) {
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1622 snprintf(buffer, buflen, "lib%s.so", fname);
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6825
diff changeset
1623 retval = true;
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1624 } else if (strchr(pname, *os::path_separator()) != NULL) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1625 int n;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1626 char** pelements = split_path(pname, &n);
9059
17bf4d428955 8006103: [parfait] Possible null pointer dereference at hotspot/src/os/linux/vm/os_linux.cpp; os_windows.cpp; os_solaris.cpp; os_bsd.cpp
ccheung
parents: 8812
diff changeset
1627 if (pelements == NULL) {
9062
dcubed
parents: 8858 9060
diff changeset
1628 return false;
9059
17bf4d428955 8006103: [parfait] Possible null pointer dereference at hotspot/src/os/linux/vm/os_linux.cpp; os_windows.cpp; os_solaris.cpp; os_bsd.cpp
ccheung
parents: 8812
diff changeset
1629 }
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1630 for (int i = 0 ; i < n ; i++) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1631 // Really shouldn't be NULL, but check can't hurt
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1632 if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1633 continue; // skip the empty path values
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1634 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1635 snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1636 if (file_exists(buffer)) {
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6825
diff changeset
1637 retval = true;
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1638 break;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1639 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1640 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1641 // release the storage
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1642 for (int i = 0 ; i < n ; i++) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1643 if (pelements[i] != NULL) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
1644 FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1645 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1646 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1647 if (pelements != NULL) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
1648 FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1649 }
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1650 } else {
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1651 snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6825
diff changeset
1652 retval = true;
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6825
diff changeset
1653 }
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6825
diff changeset
1654 return retval;
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1655 }
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1656
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
1657 // check if addr is inside libjvm.so
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 bool os::address_is_in_vm(address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 static address libjvm_base_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1661
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 if (libjvm_base_addr == NULL) {
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1663 if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1664 libjvm_base_addr = (address)dlinfo.dli_fbase;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1665 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1669 if (dladdr((void *)addr, &dlinfo) != 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1672
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1675
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 bool os::dll_address_to_function_name(address addr, char *buf,
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 int buflen, int *offset) {
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1678 // buf is not optional, but offset is optional
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1679 assert(buf != NULL, "sanity check");
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1680
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1682
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1683 if (dladdr((void*)addr, &dlinfo) != 0) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1684 // see if we have a matching symbol
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1685 if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1686 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1687 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1688 }
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1689 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1690 return true;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1691 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1692 // no matching symbol so try for just file info
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1693 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1694 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1695 buf, buflen, offset, dlinfo.dli_fname)) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1696 return true;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1697 }
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1698 }
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1699 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1700
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1701 buf[0] = '\0';
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1702 if (offset != NULL) *offset = -1;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1703 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1705
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 struct _address_to_library_name {
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 address addr; // input : memory address
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 size_t buflen; // size of fname
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 char* fname; // output: library name
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 address base; // library base addr
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1712
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 static int address_to_library_name_callback(struct dl_phdr_info *info,
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 size_t size, void *data) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 bool found = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 address libbase = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 struct _address_to_library_name * d = (struct _address_to_library_name *)data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1719
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 // iterate through all loadable segments
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 for (i = 0; i < info->dlpi_phnum; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 address segbase = (address)(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 if (info->dlpi_phdr[i].p_type == PT_LOAD) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 // base address of a library is the lowest address of its loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 // segments.
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 if (libbase == NULL || libbase > segbase) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 libbase = segbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 // see if 'addr' is within current segment
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 if (segbase <= d->addr &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 d->addr < segbase + info->dlpi_phdr[i].p_memsz) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 found = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1736
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 // dlpi_name is NULL or empty if the ELF file is executable, return 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // so dll_address_to_library_name() can fall through to use dladdr() which
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 // can figure out executable name from argv[0].
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 if (found && info->dlpi_name && info->dlpi_name[0]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 d->base = libbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 if (d->fname) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 jio_snprintf(d->fname, d->buflen, "%s", info->dlpi_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1749
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 bool os::dll_address_to_library_name(address addr, char* buf,
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 int buflen, int* offset) {
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1752 // buf is not optional, but offset is optional
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1753 assert(buf != NULL, "sanity check");
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1754
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 struct _address_to_library_name data;
a61af66fc99e Initial load
duke
parents:
diff changeset
1757
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 // There is a bug in old glibc dladdr() implementation that it could resolve
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 // to wrong library name if the .so file has a base address != NULL. Here
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 // we iterate through the program headers of all loaded libraries to find
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 // out which library 'addr' really belongs to. This workaround can be
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 // removed once the minimum requirement for glibc is moved to 2.3.x.
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 data.addr = addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 data.fname = buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 data.buflen = buflen;
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 data.base = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 int rslt = dl_iterate_phdr(address_to_library_name_callback, (void *)&data);
a61af66fc99e Initial load
duke
parents:
diff changeset
1768
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 if (rslt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 // buf already contains library name
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 if (offset) *offset = addr - data.base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 return true;
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1773 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1774 if (dladdr((void*)addr, &dlinfo) != 0) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1775 if (dlinfo.dli_fname != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1776 jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1777 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1778 if (dlinfo.dli_fbase != NULL && offset != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1779 *offset = addr - (address)dlinfo.dli_fbase;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1780 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1781 return true;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1782 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1783
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1784 buf[0] = '\0';
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1785 if (offset) *offset = -1;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1786 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1788
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 // Loads .dll/.so and
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 // in case of error it checks if .dll/.so was built for the
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 // same architecture as Hotspot is running on
a61af66fc99e Initial load
duke
parents:
diff changeset
1792
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1793
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1794 // Remember the stack's state. The Linux dynamic linker will change
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1795 // the stack to 'executable' at most once, so we must safepoint only once.
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1796 bool os::Linux::_stack_is_executable = false;
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1797
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1798 // VM operation that loads a library. This is necessary if stack protection
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1799 // of the Java stacks can be lost during loading the library. If we
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1800 // do not stop the Java threads, they can stack overflow before the stacks
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1801 // are protected again.
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1802 class VM_LinuxDllLoad: public VM_Operation {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1803 private:
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1804 const char *_filename;
8812
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
1805 char *_ebuf;
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
1806 int _ebuflen;
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1807 void *_lib;
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1808 public:
8812
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
1809 VM_LinuxDllLoad(const char *fn, char *ebuf, int ebuflen) :
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
1810 _filename(fn), _ebuf(ebuf), _ebuflen(ebuflen), _lib(NULL) {}
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1811 VMOp_Type type() const { return VMOp_LinuxDllLoad; }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1812 void doit() {
8812
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
1813 _lib = os::Linux::dll_load_in_vmthread(_filename, _ebuf, _ebuflen);
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1814 os::Linux::_stack_is_executable = true;
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1815 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1816 void* loaded_library() { return _lib; }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1817 };
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1818
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 {
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1821 void * result = NULL;
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1822 bool load_attempted = false;
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1823
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1824 // Check whether the library to load might change execution rights
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1825 // of the stack. If they are changed, the protection of the stack
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1826 // guard pages will be lost. We need a safepoint to fix this.
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1827 //
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1828 // See Linux man page execstack(8) for more info.
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1829 if (os::uses_stack_guard_pages() && !os::Linux::_stack_is_executable) {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1830 ElfFile ef(filename);
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1831 if (!ef.specifies_noexecstack()) {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1832 if (!is_init_completed()) {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1833 os::Linux::_stack_is_executable = true;
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1834 // This is OK - No Java threads have been created yet, and hence no
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1835 // stack guard pages to fix.
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1836 //
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1837 // This should happen only when you are building JDK7 using a very
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1838 // old version of JDK6 (e.g., with JPRT) and running test_gamma.
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1839 //
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1840 // Dynamic loader will make all stacks executable after
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1841 // this function returns, and will not do that again.
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1842 assert(Threads::first() == NULL, "no Java threads should exist yet.");
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1843 } else {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1844 warning("You have loaded library %s which might have disabled stack guard. "
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1845 "The VM will try to fix the stack guard now.\n"
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1846 "It's highly recommended that you fix the library with "
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1847 "'execstack -c <libfile>', or link it with '-z noexecstack'.",
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1848 filename);
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1849
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1850 assert(Thread::current()->is_Java_thread(), "must be Java thread");
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1851 JavaThread *jt = JavaThread::current();
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1852 if (jt->thread_state() != _thread_in_native) {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1853 // This happens when a compiler thread tries to load a hsdis-<arch>.so file
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1854 // that requires ExecStack. Cannot enter safe point. Let's give up.
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1855 warning("Unable to fix stack guard. Giving up.");
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1856 } else {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1857 if (!LoadExecStackDllInVMThread) {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1858 // This is for the case where the DLL has an static
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1859 // constructor function that executes JNI code. We cannot
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1860 // load such DLLs in the VMThread.
8812
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
1861 result = os::Linux::dlopen_helper(filename, ebuf, ebuflen);
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1862 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1863
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1864 ThreadInVMfromNative tiv(jt);
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1865 debug_only(VMNativeEntryWrapper vew;)
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1866
8812
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
1867 VM_LinuxDllLoad op(filename, ebuf, ebuflen);
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1868 VMThread::execute(&op);
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1869 if (LoadExecStackDllInVMThread) {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1870 result = op.loaded_library();
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1871 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1872 load_attempted = true;
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1873 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1874 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1875 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1876 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1877
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1878 if (!load_attempted) {
8812
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
1879 result = os::Linux::dlopen_helper(filename, ebuf, ebuflen);
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1880 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
1881
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 if (result != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 // Successful loading
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1886
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 Elf32_Ehdr elf_head;
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 int diag_msg_max_length=ebuflen-strlen(ebuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 char* diag_msg_buf=ebuf+strlen(ebuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1890
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 if (diag_msg_max_length==0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 // No more space in ebuf for additional diagnostics message
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1895
a61af66fc99e Initial load
duke
parents:
diff changeset
1896
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1898
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 if (file_descriptor < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 // Can't open library, report dlerror() message
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1903
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 bool failed_to_read_elf_head=
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 (sizeof(elf_head)!=
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1907
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 ::close(file_descriptor);
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 if (failed_to_read_elf_head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 // file i/o error - report dlerror() msg
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1913
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 typedef struct {
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 Elf32_Half code; // Actual value as defined in elf.h
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 Elf32_Half compat_class; // Compatibility of archs at VM's sense
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 char elf_class; // 32 or 64 bit
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 char endianess; // MSB or LSB
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 char* name; // String representation
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 } arch_t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1921
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 #ifndef EM_486
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 #define EM_486 6 /* Intel 80486 */
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1925
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 static const arch_t arch_array[]={
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 {EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 {EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 {EM_SPARC, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
17830
56e7f5560e60 8036767: PPC64: Support for little endian execution model
kvn
parents: 17810
diff changeset
1935 #if defined(VM_LITTLE_ENDIAN)
56e7f5560e60 8036767: PPC64: Support for little endian execution model
kvn
parents: 17810
diff changeset
1936 {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2LSB, (char*)"Power PC 64"},
56e7f5560e60 8036767: PPC64: Support for little endian execution model
kvn
parents: 17810
diff changeset
1937 #else
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1938 {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
17830
56e7f5560e60 8036767: PPC64: Support for little endian execution model
kvn
parents: 17810
diff changeset
1939 #endif
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1940 {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1941 {EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1942 {EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1943 {EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1944 {EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1945 {EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1946 {EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1948
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 #if (defined IA32)
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 static Elf32_Half running_arch_code=EM_386;
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 #elif (defined AMD64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 static Elf32_Half running_arch_code=EM_X86_64;
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 #elif (defined IA64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 static Elf32_Half running_arch_code=EM_IA_64;
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 #elif (defined __sparc) && (defined _LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 static Elf32_Half running_arch_code=EM_SPARCV9;
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 #elif (defined __sparc) && (!defined _LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 static Elf32_Half running_arch_code=EM_SPARC;
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 #elif (defined __powerpc64__)
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 static Elf32_Half running_arch_code=EM_PPC64;
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 #elif (defined __powerpc__)
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 static Elf32_Half running_arch_code=EM_PPC;
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1963 #elif (defined ARM)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1964 static Elf32_Half running_arch_code=EM_ARM;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1965 #elif (defined S390)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1966 static Elf32_Half running_arch_code=EM_S390;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1967 #elif (defined ALPHA)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1968 static Elf32_Half running_arch_code=EM_ALPHA;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1969 #elif (defined MIPSEL)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1970 static Elf32_Half running_arch_code=EM_MIPS_RS3_LE;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1971 #elif (defined PARISC)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1972 static Elf32_Half running_arch_code=EM_PARISC;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1973 #elif (defined MIPS)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1974 static Elf32_Half running_arch_code=EM_MIPS;
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1975 #elif (defined M68K)
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
1976 static Elf32_Half running_arch_code=EM_68K;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 #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
1979 IA32, AMD64, IA64, __sparc, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1981
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 // Identify compatability class for VM's architecture and library's architecture
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 // Obtain string descriptions for architectures
a61af66fc99e Initial load
duke
parents:
diff changeset
1984
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 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
1986 int running_arch_index=-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1987
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 if (running_arch_code == arch_array[i].code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 running_arch_index = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 if (lib_arch.code == arch_array[i].code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 lib_arch.compat_class = arch_array[i].compat_class;
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 lib_arch.name = arch_array[i].name;
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 assert(running_arch_index != -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 "Didn't find running architecture code (running_arch_code) in arch_array");
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 if (running_arch_index == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 // Even though running architecture detection failed
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 // we may still continue with reporting dlerror() message
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2005
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2010
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
2011 #ifndef S390
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 }
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
2016 #endif // !S390
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2017
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 if ( lib_arch.name!=NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 ::snprintf(diag_msg_buf, diag_msg_max_length-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 " (Possible cause: can't load %s-bit .so on a %s-bit platform)",
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 lib_arch.name, arch_array[running_arch_index].name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 ::snprintf(diag_msg_buf, diag_msg_max_length-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 lib_arch.code,
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 arch_array[running_arch_index].name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2030
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2033
8812
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2034 void * os::Linux::dlopen_helper(const char *filename, char *ebuf, int ebuflen) {
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2035 void * result = ::dlopen(filename, RTLD_LAZY);
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2036 if (result == NULL) {
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2037 ::strncpy(ebuf, ::dlerror(), ebuflen - 1);
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2038 ebuf[ebuflen-1] = '\0';
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2039 }
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2040 return result;
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2041 }
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2042
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2043 void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf, int ebuflen) {
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2044 void * result = NULL;
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2045 if (LoadExecStackDllInVMThread) {
8812
14509df4cd63 8010389: After fix for 7107135 a failed dlopen() call results in a VM crash
iklam
parents: 8711
diff changeset
2046 result = dlopen_helper(filename, ebuf, ebuflen);
8710
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2047 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2048
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2049 // Since 7019808, libjvm.so is linked with -noexecstack. If the VM loads a
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2050 // library that requires an executable stack, or which does not have this
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2051 // stack attribute set, dlopen changes the stack attribute to executable. The
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2052 // read protection of the guard pages gets lost.
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2053 //
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2054 // Need to check _stack_is_executable again as multiple VM_LinuxDllLoad
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2055 // may have been queued at the same time.
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2056
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2057 if (!_stack_is_executable) {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2058 JavaThread *jt = Threads::first();
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2059
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2060 while (jt) {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2061 if (!jt->stack_guard_zone_unused() && // Stack not yet fully initialized
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2062 jt->stack_yellow_zone_enabled()) { // No pending stack overflow exceptions
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2063 if (!os::guard_memory((char *) jt->stack_red_zone_base() - jt->stack_red_zone_size(),
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2064 jt->stack_yellow_zone_size() + jt->stack_red_zone_size())) {
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2065 warning("Attempt to reguard stack yellow zone failed.");
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2066 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2067 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2068 jt = jt->next();
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2069 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2070 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2071
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2072 return result;
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2073 }
9058789475af 7107135: Stack guard pages are no more protected after loading a shared library with executable stack
iklam
parents: 8675
diff changeset
2074
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2075 /*
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2076 * 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
2077 * 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
2078 * libdl.so, so always use locking for any version of glibc.
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2079 */
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2080 void* os::dll_lookup(void* handle, const char* name) {
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2081 pthread_mutex_lock(&dl_mutex);
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2082 void* res = dlsym(handle, name);
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2083 pthread_mutex_unlock(&dl_mutex);
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2084 return res;
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2085 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2086
17684
d1621038becf 8031968: Mac OS X: VM starts the agent by calling both Agent_OnAttach and Agent_OnAttach_L functions if its agent library is dynamically linked.
sla
parents: 12997
diff changeset
2087 void* os::get_default_process_handle() {
d1621038becf 8031968: Mac OS X: VM starts the agent by calling both Agent_OnAttach and Agent_OnAttach_L functions if its agent library is dynamically linked.
sla
parents: 12997
diff changeset
2088 return (void*)::dlopen(NULL, RTLD_LAZY);
d1621038becf 8031968: Mac OS X: VM starts the agent by calling both Agent_OnAttach and Agent_OnAttach_L functions if its agent library is dynamically linked.
sla
parents: 12997
diff changeset
2089 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2090
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2091 static bool _print_ascii_file(const char* filename, outputStream* st) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2092 int fd = ::open(filename, O_RDONLY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 if (fd == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2096
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 char buf[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 int bytes;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2099 while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 st->print_raw(buf, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2102
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2103 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2104
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2107
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 void os::print_dll_info(outputStream *st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 st->print_cr("Dynamic libraries:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2110
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 char fname[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 pid_t pid = os::Linux::gettid();
a61af66fc99e Initial load
duke
parents:
diff changeset
2113
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 jio_snprintf(fname, sizeof(fname), "/proc/%d/maps", pid);
a61af66fc99e Initial load
duke
parents:
diff changeset
2115
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 if (!_print_ascii_file(fname, st)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 st->print("Can not get library information for pid = %d\n", pid);
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2120
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2121 void os::print_os_info_brief(outputStream* st) {
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2122 os::Linux::print_distro_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2123
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2124 os::Posix::print_uname_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2125
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2126 os::Linux::print_libversion_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2127
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2128 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2129
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 void os::print_os_info(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 st->print("OS:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2133 os::Linux::print_distro_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2134
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2135 os::Posix::print_uname_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2136
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2137 // Print warning if unsafe chroot environment detected
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2138 if (unsafe_chroot_detected) {
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2139 st->print("WARNING!! ");
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
2140 st->print_cr("%s", unstable_chroot_error);
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2141 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2142
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2143 os::Linux::print_libversion_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2144
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2145 os::Posix::print_rlimit_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2146
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2147 os::Posix::print_load_average(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2148
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2149 os::Linux::print_full_memory_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2150 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2151
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2152 // Try to identify popular distros.
12212
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2153 // Most Linux distributions have a /etc/XXX-release file, which contains
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2154 // the OS version string. Newer Linux distributions have a /etc/lsb-release
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2155 // file that also contains the OS version string. Some have more than one
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2156 // /etc/XXX-release file (e.g. Mandrake has both /etc/mandrake-release and
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2157 // /etc/redhat-release.), so the order is important.
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2158 // Any Linux that is based on Redhat (i.e. Oracle, Mandrake, Sun JDS...) have
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2159 // their own specific XXX-release file as well as a redhat-release file.
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2160 // Because of this the XXX-release file needs to be searched for before the
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2161 // redhat-release file.
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2162 // Since Red Hat has a lsb-release file that is not very descriptive the
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2163 // search for redhat-release needs to be before lsb-release.
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2164 // Since the lsb-release file is the new standard it needs to be searched
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2165 // before the older style release files.
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2166 // Searching system-release (Red Hat) and os-release (other Linuxes) are a
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2167 // next to last resort. The os-release file is a new standard that contains
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2168 // distribution information and the system-release file seems to be an old
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2169 // standard that has been replaced by the lsb-release and os-release files.
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2170 // Searching for the debian_version file is the last resort. It contains
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2171 // an informative string like "6.0.6" or "wheezy/sid". Because of this
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2172 // "Debian " is printed before the contents of the debian_version file.
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2173 void os::Linux::print_distro_info(outputStream* st) {
12212
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2174 if (!_print_ascii_file("/etc/oracle-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2175 !_print_ascii_file("/etc/mandriva-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2176 !_print_ascii_file("/etc/mandrake-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2177 !_print_ascii_file("/etc/sun-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2178 !_print_ascii_file("/etc/redhat-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2179 !_print_ascii_file("/etc/lsb-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2180 !_print_ascii_file("/etc/SuSE-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2181 !_print_ascii_file("/etc/turbolinux-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2182 !_print_ascii_file("/etc/gentoo-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2183 !_print_ascii_file("/etc/ltib-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2184 !_print_ascii_file("/etc/angstrom-version", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2185 !_print_ascii_file("/etc/system-release", st) &&
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2186 !_print_ascii_file("/etc/os-release", st)) {
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2187
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2188 if (file_exists("/etc/debian_version")) {
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2189 st->print("Debian ");
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2190 _print_ascii_file("/etc/debian_version", st);
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2191 } else {
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2192 st->print("Linux");
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2193 }
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2194 }
4472884d8b37 6986195: correctly identify Ubuntu as the operating system in crash report instead of "Debian"
dcubed
parents: 12211
diff changeset
2195 st->cr();
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2196 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2197
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2198 void os::Linux::print_libversion_info(outputStream* st) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 // libc, pthread
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 st->print("libc:");
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
2201 st->print("%s ", os::Linux::glibc_version());
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
2202 st->print("%s ", os::Linux::libpthread_version());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 if (os::Linux::is_LinuxThreads()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 st->print("(%s stack)", os::Linux::is_floating_stack() ? "floating" : "fixed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 st->cr();
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2207 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2208
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2209 void os::Linux::print_full_memory_info(outputStream* st) {
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2210 st->print("\n/proc/meminfo:\n");
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2211 _print_ascii_file("/proc/meminfo", st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2212 st->cr();
3800
bf6481e5f96d 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 3358
diff changeset
2213 }
bf6481e5f96d 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 3358
diff changeset
2214
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 void os::print_memory_info(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2216
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 st->print("Memory:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 st->print(" %dk page", os::vm_page_size()>>10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2219
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 // values in struct sysinfo are "unsigned long"
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 struct sysinfo si;
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 sysinfo(&si);
a61af66fc99e Initial load
duke
parents:
diff changeset
2223
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 st->print(", physical " UINT64_FORMAT "k",
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 os::physical_memory() >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 st->print("(" UINT64_FORMAT "k free)",
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 os::available_memory() >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 st->print(", swap " UINT64_FORMAT "k",
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 ((jlong)si.totalswap * si.mem_unit) >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 st->print("(" UINT64_FORMAT "k free)",
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 ((jlong)si.freeswap * si.mem_unit) >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2234
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2235 void os::pd_print_cpu_info(outputStream* st) {
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2236 st->print("\n/proc/cpuinfo:\n");
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2237 if (!_print_ascii_file("/proc/cpuinfo", st)) {
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2238 st->print(" <Not Available>");
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2239 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2240 st->cr();
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2241 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5937
diff changeset
2242
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 void os::print_siginfo(outputStream* st, void* siginfo) {
14410
f42f2e2a1518 8020775: PPC64 (part 12): posix signal printing
goetz
parents: 14405
diff changeset
2244 const siginfo_t* si = (const siginfo_t*)siginfo;
f42f2e2a1518 8020775: PPC64 (part 12): posix signal printing
goetz
parents: 14405
diff changeset
2245
f42f2e2a1518 8020775: PPC64 (part 12): posix signal printing
goetz
parents: 14405
diff changeset
2246 os::Posix::print_siginfo_brief(st, si);
f42f2e2a1518 8020775: PPC64 (part 12): posix signal printing
goetz
parents: 14405
diff changeset
2247
f42f2e2a1518 8020775: PPC64 (part 12): posix signal printing
goetz
parents: 14405
diff changeset
2248 if (si && (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 UseSharedSpaces) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 FileMapInfo* mapinfo = FileMapInfo::current_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 if (mapinfo->is_in_shared_space(si->si_addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 st->print("\n\nError accessing class data sharing archive." \
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 " Mapped file inaccessible during execution, " \
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 " possible disk/network problem.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2259
a61af66fc99e Initial load
duke
parents:
diff changeset
2260
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 static void print_signal_handler(outputStream* st, int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 char* buf, size_t buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2263
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 st->print_cr("Signal Handlers:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 print_signal_handler(st, SIGSEGV, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 print_signal_handler(st, SIGBUS , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 print_signal_handler(st, SIGFPE , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 print_signal_handler(st, SIGPIPE, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 print_signal_handler(st, SIGXFSZ, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 print_signal_handler(st, SIGILL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 print_signal_handler(st, SR_signum, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 print_signal_handler(st, SHUTDOWN1_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 print_signal_handler(st, SHUTDOWN3_SIGNAL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
14432
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
2278 #if defined(PPC64)
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
2279 print_signal_handler(st, SIGTRAP, buf, buflen);
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
2280 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2282
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 static char saved_jvm_path[MAXPATHLEN] = {0};
a61af66fc99e Initial load
duke
parents:
diff changeset
2284
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
2285 // Find the full path to the current module, libjvm.so
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2286 void os::jvm_path(char *buf, jint buflen) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 // Error checking.
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2288 if (buflen < MAXPATHLEN) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 assert(false, "must use a large-enough buffer");
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 buf[0] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 // Lazy resolve the path to current module.
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 if (saved_jvm_path[0] != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 strcpy(buf, saved_jvm_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2298
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 char dli_fname[MAXPATHLEN];
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 bool ret = dll_address_to_library_name(
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 CAST_FROM_FN_PTR(address, os::jvm_path),
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 dli_fname, sizeof(dli_fname), NULL);
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2303 assert(ret, "cannot locate libjvm");
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2304 char *rp = NULL;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2305 if (ret && dli_fname[0] != '\0') {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2306 rp = realpath(dli_fname, buf);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2307 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2308 if (rp == NULL)
513
2328d1d3f8cf 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 477
diff changeset
2309 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2310
2302
da091bb67459 7022037: Pause when exiting if debugger is attached on windows
sla
parents: 2204
diff changeset
2311 if (Arguments::created_by_gamma_launcher()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 // Support for the gamma launcher. Typical value for buf is
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 // the right place in the string, then assume we are installed in a JDK and
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 // we're done. Otherwise, check for a JAVA_HOME environment variable and fix
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 // up the path so it looks like libjvm.so is installed there (append a
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 // fake suffix hotspot/libjvm.so).
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 const char *p = buf + strlen(buf) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 for (int count = 0; p > buf && count < 5; ++count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 for (--p; p > buf && *p != '/'; --p)
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 /* empty */ ;
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2323
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 if (strncmp(p, "/jre/lib/", 9) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 // Look for JAVA_HOME in the environment.
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 char* java_home_var = ::getenv("JAVA_HOME");
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 if (java_home_var != NULL && java_home_var[0] != 0) {
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2328 char* jrelib_p;
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2329 int len;
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2330
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
2331 // Check the current module name "libjvm.so".
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 p = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 assert(strstr(p, "/libjvm") == p, "invalid library name");
a61af66fc99e Initial load
duke
parents:
diff changeset
2334
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2335 rp = realpath(java_home_var, buf);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2336 if (rp == NULL)
513
2328d1d3f8cf 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 477
diff changeset
2337 return;
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2338
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2339 // determine if this is a legacy image or modules image
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2340 // modules image doesn't have "jre" subdirectory
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2341 len = strlen(buf);
17567
5656140324ed 8030763: Validate global memory allocation
hseigel
parents: 12997
diff changeset
2342 assert(len < buflen, "Ran out of buffer room");
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2343 jrelib_p = buf + len;
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2344 snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2345 if (0 != access(buf, F_OK)) {
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2346 snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2347 }
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2348
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 if (0 == access(buf, F_OK)) {
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
2350 // Use current module name "libjvm.so"
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2351 len = strlen(buf);
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
2352 snprintf(buf + len, buflen-len, "/hotspot/libjvm.so");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 // Go back to path of .so
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2355 rp = realpath(dli_fname, buf);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2356 if (rp == NULL)
513
2328d1d3f8cf 6781583: Hotspot build fails on linux 64 bit platform with gcc 4.3.2
xlu
parents: 477
diff changeset
2357 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
17567
5656140324ed 8030763: Validate global memory allocation
hseigel
parents: 12997
diff changeset
2363 strncpy(saved_jvm_path, buf, MAXPATHLEN);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2365
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 // no prefix required, not even "_"
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2369
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 void os::print_jni_name_suffix_on(outputStream* st, int args_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 // no suffix required
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2373
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 // sun.misc.Signal support
a61af66fc99e Initial load
duke
parents:
diff changeset
2376
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 static volatile jint sigint_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2378
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 static void
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 UserHandler(int sig, void *siginfo, void *context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 // 4511530 - sem_post is serialized and handled by the manager thread. When
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 // don't want to flood the manager thread with sem_post requests.
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2386
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 // Ctrl-C is pressed during error reporting, likely because the error
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 // handler fails to abort. Let VM die immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 if (sig == SIGINT && is_error_reported()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 os::die();
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2392
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 os::signal_notify(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2395
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 void* os::user_handler() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 return CAST_FROM_FN_PTR(void*, UserHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2399
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2400 class Semaphore : public StackObj {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2401 public:
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2402 Semaphore();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2403 ~Semaphore();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2404 void signal();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2405 void wait();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2406 bool trywait();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2407 bool timedwait(unsigned int sec, int nsec);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2408 private:
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2409 sem_t _semaphore;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2410 };
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2411
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2412 Semaphore::Semaphore() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2413 sem_init(&_semaphore, 0, 0);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2414 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2415
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2416 Semaphore::~Semaphore() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2417 sem_destroy(&_semaphore);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2418 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2419
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2420 void Semaphore::signal() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2421 sem_post(&_semaphore);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2422 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2423
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2424 void Semaphore::wait() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2425 sem_wait(&_semaphore);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2426 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2427
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2428 bool Semaphore::trywait() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2429 return sem_trywait(&_semaphore) == 0;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2430 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2431
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2432 bool Semaphore::timedwait(unsigned int sec, int nsec) {
17738
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2433
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2434 struct timespec ts;
17738
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2435 // Semaphore's are always associated with CLOCK_REALTIME
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2436 os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2437 // see unpackTime for discussion on overflow checking
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2438 if (sec >= MAX_SECS) {
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2439 ts.tv_sec += MAX_SECS;
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2440 ts.tv_nsec = 0;
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2441 } else {
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2442 ts.tv_sec += sec;
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2443 ts.tv_nsec += nsec;
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2444 if (ts.tv_nsec >= NANOSECS_PER_SEC) {
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2445 ts.tv_nsec -= NANOSECS_PER_SEC;
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2446 ++ts.tv_sec; // note: this must be <= max_secs
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2447 }
8cfe6fdbb99a 8037340: Linux semaphores to use CLOCK_REALTIME
mgronlun
parents: 17706
diff changeset
2448 }
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2449
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2450 while (1) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2451 int result = sem_timedwait(&_semaphore, &ts);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2452 if (result == 0) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2453 return true;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2454 } else if (errno == EINTR) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2455 continue;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2456 } else if (errno == ETIMEDOUT) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2457 return false;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2458 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2459 return false;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2460 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2461 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2462 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2463
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 typedef void (*sa_handler_t)(int);
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2468
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 void* os::signal(int signal_number, void* handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 struct sigaction sigAct, oldSigAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
2471
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 sigfillset(&(sigAct.sa_mask));
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 sigAct.sa_flags = SA_RESTART|SA_SIGINFO;
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2475
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 if (sigaction(signal_number, &sigAct, &oldSigAct)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 // -1 means registration failed
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 return (void *)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2480
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2483
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 void os::signal_raise(int signal_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 ::raise(signal_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2487
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 * The following code is moved from os.cpp for making this
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 * code platform specific, which it is by its very nature.
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 */
a61af66fc99e Initial load
duke
parents:
diff changeset
2492
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 // Will be modified when max signal is changed to be dynamic
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 int os::sigexitnum_pd() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 return NSIG;
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2497
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 // a counter for each possible signal value
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 static volatile jint pending_signals[NSIG+1] = { 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2500
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 // Linux(POSIX) specific hand shaking semaphore.
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 static sem_t sig_sem;
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
2503 static Semaphore sr_semaphore;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2504
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 void os::signal_init_pd() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 // Initialize signal structures
a61af66fc99e Initial load
duke
parents:
diff changeset
2507 ::memset((void*)pending_signals, 0, sizeof(pending_signals));
a61af66fc99e Initial load
duke
parents:
diff changeset
2508
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 // Initialize signal semaphore
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 ::sem_init(&sig_sem, 0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2512
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 void os::signal_notify(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 Atomic::inc(&pending_signals[sig]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 ::sem_post(&sig_sem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2517
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 static int check_pending_signals(bool wait) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 Atomic::store(0, &sigint_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 for (int i = 0; i < NSIG + 1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 jint n = pending_signals[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 if (!wait) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 JavaThread *thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 ThreadBlockInVM tbivm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2532
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 bool threadIsSuspended;
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 thread->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 ::sem_wait(&sig_sem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2538
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 if (threadIsSuspended) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 // The semaphore has been incremented, but while we were waiting
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 // another thread suspended us. We don't want to continue running
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 // while suspended because that would surprise the thread that
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 // suspended us.
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 ::sem_post(&sig_sem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2549
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 thread->java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 } while (threadIsSuspended);
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2555
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 int os::signal_lookup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 return check_pending_signals(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2559
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 int os::signal_wait() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 return check_pending_signals(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2563
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 // Virtual Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2566
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 int os::vm_page_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 // Seems redundant as all get out
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 assert(os::Linux::page_size() != -1, "must call os::init");
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 return os::Linux::page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2572
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 // Solaris allocates memory by pages.
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 int os::vm_allocation_granularity() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 assert(os::Linux::page_size() != -1, "must call os::init");
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 return os::Linux::page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2578
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 // Rationale behind this function:
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 // current (Mon Apr 25 20:12:18 MSD 2005) oprofile drops samples without executable
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 // mapping for address (see lookup_dcookie() in the kernel module), thus we cannot get
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 // samples for JITted code. Here we create private executable mapping over the code cache
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 // and then we can use standard (well, almost, as mapping can change) way to provide
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 // info for the reporting script by storing timestamp and location of symbol
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 void linux_wrap_code(char* base, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 static volatile jint cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2587
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 if (!UseOprofile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2591
1497
96d554193f72 6944822: Fix for 6938627 exposes problem with hard-coded buffer sizes
coleenp
parents: 1353
diff changeset
2592 char buf[PATH_MAX+1];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 int num = Atomic::add(1, &cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
2594
1353
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 1325
diff changeset
2595 snprintf(buf, sizeof(buf), "%s/hs-vm-%d-%d",
a2ea687fdc7c 6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents: 1325
diff changeset
2596 os::get_temp_directory(), os::current_process_id(), num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 unlink(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2598
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2599 int fd = ::open(buf, O_CREAT | O_RDWR, S_IRWXU);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2600
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 if (fd != -1) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2602 off_t rv = ::lseek(fd, size-2, SEEK_SET);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 if (rv != (off_t)-1) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2604 if (::write(fd, "", 1) == 1) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 mmap(base, size,
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 PROT_READ|PROT_WRITE|PROT_EXEC,
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, fd, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 }
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2610 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 unlink(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2614
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2615 static bool recoverable_mmap_error(int err) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2616 // See if the error is one we can let the caller handle. This
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2617 // list of errno values comes from JBS-6843484. I can't find a
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2618 // Linux man page that documents this specific set of errno
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2619 // values so while this list currently matches Solaris, it may
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2620 // change as we gain experience with this failure mode.
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2621 switch (err) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2622 case EBADF:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2623 case EINVAL:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2624 case ENOTSUP:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2625 // let the caller deal with these errors
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2626 return true;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2627
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2628 default:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2629 // Any remaining errors on this OS can cause our reserved mapping
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2630 // to be lost. That can cause confusion where different data
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2631 // structures think they have the same memory mapped. The worst
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2632 // scenario is if both the VM and a library think they have the
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2633 // same memory mapped.
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2634 return false;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2635 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2636 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2637
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2638 static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2639 int err) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2640 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2641 ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2642 strerror(err), err);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2643 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2644
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2645 static void warn_fail_commit_memory(char* addr, size_t size,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2646 size_t alignment_hint, bool exec,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2647 int err) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2648 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2649 ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, size,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2650 alignment_hint, exec, strerror(err), err);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2651 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2652
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 // NOTE: Linux kernel does not really reserve the pages for us.
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 // All it does is to check if there are enough free pages
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 // left at the time of mmap(). This could be a potential
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 // problem.
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2657 int os::Linux::commit_memory_impl(char* addr, size_t size, bool exec) {
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2658 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2659 uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
3885
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3826
diff changeset
2661 if (res != (uintptr_t) MAP_FAILED) {
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3826
diff changeset
2662 if (UseNUMAInterleaving) {
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3826
diff changeset
2663 numa_make_global(addr, size);
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3826
diff changeset
2664 }
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2665 return 0;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2666 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2667
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2668 int err = errno; // save errno from mmap() call above
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2669
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2670 if (!recoverable_mmap_error(err)) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2671 warn_fail_commit_memory(addr, size, exec, err);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2672 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "committing reserved memory.");
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2673 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2674
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2675 return err;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2676 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2677
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2678 bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2679 return os::Linux::commit_memory_impl(addr, size, exec) == 0;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2680 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2681
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2682 void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2683 const char* mesg) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2684 assert(mesg != NULL, "mesg must be specified");
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2685 int err = os::Linux::commit_memory_impl(addr, size, exec);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2686 if (err != 0) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2687 // the caller wants all commit errors to exit with the specified mesg:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2688 warn_fail_commit_memory(addr, size, exec, err);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2689 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2690 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2692
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2693 // Define MAP_HUGETLB here so we can build HotSpot on old systems.
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2694 #ifndef MAP_HUGETLB
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2695 #define MAP_HUGETLB 0x40000
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2696 #endif
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2697
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2698 // Define MADV_HUGEPAGE here so we can build HotSpot on old systems.
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2699 #ifndef MADV_HUGEPAGE
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2700 #define MADV_HUGEPAGE 14
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2701 #endif
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2702
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2703 int os::Linux::commit_memory_impl(char* addr, size_t size,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2704 size_t alignment_hint, bool exec) {
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
2705 int err = os::Linux::commit_memory_impl(addr, size, exec);
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2706 if (err == 0) {
3913
27702f012017 7087583: Hotspot fails to allocate heap with mmap(MAP_HUGETLB)
iveresov
parents: 3887
diff changeset
2707 realign_memory(addr, size, alignment_hint);
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2708 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2709 return err;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2710 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2711
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2712 bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2713 bool exec) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2714 return os::Linux::commit_memory_impl(addr, size, alignment_hint, exec) == 0;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2715 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2716
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2717 void os::pd_commit_memory_or_exit(char* addr, size_t size,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2718 size_t alignment_hint, bool exec,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2719 const char* mesg) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2720 assert(mesg != NULL, "mesg must be specified");
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2721 int err = os::Linux::commit_memory_impl(addr, size, alignment_hint, exec);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2722 if (err != 0) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2723 // the caller wants all commit errors to exit with the specified mesg:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2724 warn_fail_commit_memory(addr, size, alignment_hint, exec, err);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2725 vm_exit_out_of_memory(size, OOM_MMAP_ERROR, mesg);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2726 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2728
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2729 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
2730 if (UseTransparentHugePages && alignment_hint > (size_t)vm_page_size()) {
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2731 // We don't check the return value: madvise(MADV_HUGEPAGE) may not
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2732 // be supported or the memory may already be backed by huge pages.
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2733 ::madvise(addr, bytes, MADV_HUGEPAGE);
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2734 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
2735 }
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2736
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2737 void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {
5937
cf956638b844 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 5909
diff changeset
2738 // This method works by doing an mmap over an existing mmaping and effectively discarding
cf956638b844 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 5909
diff changeset
2739 // the existing pages. However it won't work for SHM-based large pages that cannot be
cf956638b844 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 5909
diff changeset
2740 // uncommitted at all. We don't do anything in this case to avoid creating a segment with
cf956638b844 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 5909
diff changeset
2741 // small pages on top of the SHM segment. This method always works for small pages, so we
cf956638b844 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 5909
diff changeset
2742 // allow that in any case.
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
2743 if (alignment_hint <= (size_t)os::vm_page_size() || can_commit_large_page_memory()) {
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2744 commit_memory(addr, bytes, alignment_hint, !ExecMem);
5937
cf956638b844 7151089: PS NUMA: NUMA allocator should not attempt to free pages when using SHM large pages
iveresov
parents: 5909
diff changeset
2745 }
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2746 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2747
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2748 void os::numa_make_global(char *addr, size_t bytes) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2749 Linux::numa_interleave_memory(addr, bytes);
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2750 }
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2751
12176
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2752 // Define for numa_set_bind_policy(int). Setting the argument to 0 will set the
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2753 // bind policy to MPOL_PREFERRED for the current thread.
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2754 #define USE_MPOL_PREFERRED 0
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2755
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2756 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
12176
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2757 // To make NUMA and large pages more robust when both enabled, we need to ease
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2758 // the requirements on where the memory should be allocated. MPOL_BIND is the
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2759 // default policy and it will force memory to be allocated on the specified
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2760 // node. Changing this to MPOL_PREFERRED will prefer to allocate the memory on
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2761 // the specified node, but will not force it. Using this policy will prevent
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2762 // getting SIGBUS when trying to allocate large pages on NUMA nodes with no
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2763 // free large pages.
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2764 Linux::numa_set_bind_policy(USE_MPOL_PREFERRED);
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2765 Linux::numa_tonode_memory(addr, bytes, lgrp_hint);
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2766 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2767
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2768 bool os::numa_topology_changed() { return false; }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2769
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2770 size_t os::numa_get_groups_num() {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2771 int max_node = Linux::numa_max_node();
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2772 return max_node > 0 ? max_node + 1 : 1;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2773 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2774
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2775 int os::numa_get_group_id() {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2776 int cpu_id = Linux::sched_getcpu();
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2777 if (cpu_id != -1) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2778 int lgrp_id = Linux::get_node_by_cpu(cpu_id);
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2779 if (lgrp_id != -1) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2780 return lgrp_id;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2781 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2785
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2786 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
2787 for (size_t i = 0; i < size; i++) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2788 ids[i] = i;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2789 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2790 return size;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2791 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2792
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 bool os::get_page_info(char *start, page_info* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2796
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 return end;
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2800
3826
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2801
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2802 int os::Linux::sched_getcpu_syscall(void) {
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2803 unsigned int cpu;
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2804 int retval = -1;
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2805
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2806 #if defined(IA32)
3887
9447b2fb6fcf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 3885
diff changeset
2807 # ifndef SYS_getcpu
9447b2fb6fcf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 3885
diff changeset
2808 # define SYS_getcpu 318
9447b2fb6fcf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 3885
diff changeset
2809 # endif
3826
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2810 retval = syscall(SYS_getcpu, &cpu, NULL, NULL);
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2811 #elif defined(AMD64)
3887
9447b2fb6fcf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 3885
diff changeset
2812 // Unfortunately we have to bring all these macros here from vsyscall.h
9447b2fb6fcf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 3885
diff changeset
2813 // to be able to compile on old linuxes.
9447b2fb6fcf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 3885
diff changeset
2814 # define __NR_vgetcpu 2
9447b2fb6fcf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 3885
diff changeset
2815 # define VSYSCALL_START (-10UL << 20)
9447b2fb6fcf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 3885
diff changeset
2816 # define VSYSCALL_SIZE 1024
9447b2fb6fcf 7082645: Hotspot doesn't compile on old linuxes after 7060836
iveresov
parents: 3885
diff changeset
2817 # define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr))
3826
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2818 typedef long (*vgetcpu_t)(unsigned int *cpu, unsigned int *node, unsigned long *tcache);
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2819 vgetcpu_t vgetcpu = (vgetcpu_t)VSYSCALL_ADDR(__NR_vgetcpu);
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2820 retval = vgetcpu(&cpu, NULL, NULL);
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2821 #endif
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2822
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2823 return (retval == -1) ? retval : cpu;
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2824 }
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2825
2191
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
2826 // Something to do with the numa-aware allocator needs these symbols
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
2827 extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { }
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
2828 extern "C" JNIEXPORT void numa_error(char *where) { }
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
2829 extern "C" JNIEXPORT int fork1() { return fork(); }
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2830
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2831
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2832 // If we are running with libnuma version > 2, then we should
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2833 // be trying to use symbols with versions 1.1
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2834 // If we are running with earlier version, which did not have symbol versions,
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2835 // we should use the base version.
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2836 void* os::Linux::libnuma_dlsym(void* handle, const char *name) {
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2837 void *f = dlvsym(handle, name, "libnuma_1.1");
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2838 if (f == NULL) {
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2839 f = dlsym(handle, name);
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2840 }
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2841 return f;
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2842 }
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2843
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2844 bool os::Linux::libnuma_init() {
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2845 // sched_getcpu() should be in libc.
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2846 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t,
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2847 dlsym(RTLD_DEFAULT, "sched_getcpu")));
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2848
3826
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2849 // If it's not, try a direct syscall.
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2850 if (sched_getcpu() == -1)
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2851 set_sched_getcpu(CAST_TO_FN_PTR(sched_getcpu_func_t, (void*)&sched_getcpu_syscall));
7c2653aefc46 7060836: RHEL 5.5 and 5.6 should support UseNUMA
iveresov
parents: 3825
diff changeset
2852
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2853 if (sched_getcpu() != -1) { // Does it work?
267
9d6a3a6891f8 6720130: NUMA allocator: The linux version should search for libnuma.so.1
iveresov
parents: 199
diff changeset
2854 void *handle = dlopen("libnuma.so.1", RTLD_LAZY);
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2855 if (handle != NULL) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2856 set_numa_node_to_cpus(CAST_TO_FN_PTR(numa_node_to_cpus_func_t,
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2857 libnuma_dlsym(handle, "numa_node_to_cpus")));
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2858 set_numa_max_node(CAST_TO_FN_PTR(numa_max_node_func_t,
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2859 libnuma_dlsym(handle, "numa_max_node")));
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2860 set_numa_available(CAST_TO_FN_PTR(numa_available_func_t,
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2861 libnuma_dlsym(handle, "numa_available")));
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2862 set_numa_tonode_memory(CAST_TO_FN_PTR(numa_tonode_memory_func_t,
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2863 libnuma_dlsym(handle, "numa_tonode_memory")));
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2864 set_numa_interleave_memory(CAST_TO_FN_PTR(numa_interleave_memory_func_t,
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2865 libnuma_dlsym(handle, "numa_interleave_memory")));
12176
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2866 set_numa_set_bind_policy(CAST_TO_FN_PTR(numa_set_bind_policy_func_t,
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2867 libnuma_dlsym(handle, "numa_set_bind_policy")));
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2868
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2869
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2870 if (numa_available() != -1) {
763
cf71f149d7ae 6840196: NUMA allocator: crash in fastdebug during startup on Linux
iveresov
parents: 761
diff changeset
2871 set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes"));
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2872 // Create a cpu -> node mapping
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2873 _cpu_to_node = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int>(0, true);
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2874 rebuild_cpu_to_node_map();
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2875 return true;
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2876 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2877 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2878 }
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2879 return false;
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2880 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2881
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2882 // 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
2883 // The table is later used in get_node_by_cpu().
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2884 void os::Linux::rebuild_cpu_to_node_map() {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2885 const size_t NCPUS = 32768; // Since the buffer size computation is very obscure
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2886 // in libnuma (possible values are starting from 16,
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2887 // and continuing up with every other power of 2, but less
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2888 // than the maximum number of CPUs supported by kernel), and
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2889 // is a subject to change (in libnuma version 2 the requirements
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2890 // are more reasonable) we'll just hardcode the number they use
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2891 // in the library.
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2892 const size_t BitsPerCLong = sizeof(long) * CHAR_BIT;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2893
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2894 size_t cpu_num = os::active_processor_count();
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2895 size_t cpu_map_size = NCPUS / BitsPerCLong;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2896 size_t cpu_map_valid_size =
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2897 MIN2((cpu_num + BitsPerCLong - 1) / BitsPerCLong, cpu_map_size);
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2898
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2899 cpu_to_node()->clear();
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2900 cpu_to_node()->at_grow(cpu_num - 1);
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2901 size_t node_num = numa_get_groups_num();
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2902
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2903 unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size, mtInternal);
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2904 for (size_t i = 0; i < node_num; i++) {
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2905 if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2906 for (size_t j = 0; j < cpu_map_valid_size; j++) {
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2907 if (cpu_map[j] != 0) {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2908 for (size_t k = 0; k < BitsPerCLong; k++) {
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2909 if (cpu_map[j] & (1UL << k)) {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2910 cpu_to_node()->at_put(j * BitsPerCLong + k, i);
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2911 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2912 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2913 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2914 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2915 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2916 }
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2917 FREE_C_HEAP_ARRAY(unsigned long, cpu_map, mtInternal);
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2918 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2919
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2920 int os::Linux::get_node_by_cpu(int cpu_id) {
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2921 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
2922 return cpu_to_node()->at(cpu_id);
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2923 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2924 return -1;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2925 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2926
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2927 GrowableArray<int>* os::Linux::_cpu_to_node;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2928 os::Linux::sched_getcpu_func_t os::Linux::_sched_getcpu;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2929 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
2930 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
2931 os::Linux::numa_available_func_t os::Linux::_numa_available;
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2932 os::Linux::numa_tonode_memory_func_t os::Linux::_numa_tonode_memory;
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2933 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory;
12176
88c255656030 8016155: SIGBUS when running Kitchensink with ParallelScavenge and ParallelOld
mgerdin
parents: 11092
diff changeset
2934 os::Linux::numa_set_bind_policy_func_t os::Linux::_numa_set_bind_policy;
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
2935 unsigned long* os::Linux::_numa_all_nodes;
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
2936
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2937 bool os::pd_uncommit_memory(char* addr, size_t size) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2938 uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2939 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2940 return res != (uintptr_t) MAP_FAILED;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2942
12144
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2943 static
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2944 address get_stack_commited_bottom(address bottom, size_t size) {
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2945 address nbot = bottom;
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2946 address ntop = bottom + size;
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2947
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2948 size_t page_sz = os::vm_page_size();
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2949 unsigned pages = size / page_sz;
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2950
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2951 unsigned char vec[1];
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2952 unsigned imin = 1, imax = pages + 1, imid;
17765
91dc38ae09f3 8033464: Linux code cleanup
dcubed
parents: 17738
diff changeset
2953 int mincore_return_value = 0;
91dc38ae09f3 8033464: Linux code cleanup
dcubed
parents: 17738
diff changeset
2954
91dc38ae09f3 8033464: Linux code cleanup
dcubed
parents: 17738
diff changeset
2955 assert(imin <= imax, "Unexpected page size");
12144
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2956
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2957 while (imin < imax) {
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2958 imid = (imax + imin) / 2;
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2959 nbot = ntop - (imid * page_sz);
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2960
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2961 // Use a trick with mincore to check whether the page is mapped or not.
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2962 // mincore sets vec to 1 if page resides in memory and to 0 if page
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2963 // is swapped output but if page we are asking for is unmapped
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2964 // it returns -1,ENOMEM
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2965 mincore_return_value = mincore(nbot, page_sz, vec);
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2966
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2967 if (mincore_return_value == -1) {
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2968 // Page is not mapped go up
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2969 // to find first mapped page
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2970 if (errno != EAGAIN) {
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2971 assert(errno == ENOMEM, "Unexpected mincore errno");
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2972 imax = imid;
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2973 }
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2974 } else {
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2975 // Page is mapped go down
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2976 // to find first not mapped page
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2977 imin = imid + 1;
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2978 }
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2979 }
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2980
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2981 nbot = nbot + page_sz;
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2982
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2983 // Adjust stack bottom one page up if last checked page is not mapped
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2984 if (mincore_return_value == -1) {
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2985 nbot = nbot + page_sz;
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2986 }
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2987
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2988 return nbot;
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2989 }
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2990
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
2991
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2992 // Linux uses a growable mapping for the stack, and if the mapping for
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2993 // the stack guard pages is not removed when we detach a thread the
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2994 // stack cannot grow beyond the pages where the stack guard was
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2995 // mapped. If at some point later in the process the stack expands to
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2996 // that point, the Linux kernel cannot expand the stack any further
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2997 // because the guard pages are in the way, and a segfault occurs.
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2998 //
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2999 // However, it's essential not to split the stack region by unmapping
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3000 // a region (leaving a hole) that's already part of the stack mapping,
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3001 // so if the stack mapping has already grown beyond the guard pages at
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3002 // the time we create them, we have to truncate the stack mapping.
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3003 // So, we need to know the extent of the stack mapping when
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3004 // create_stack_guard_pages() is called.
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3005
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3006 // We only need this for stacks that are growable: at the time of
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3007 // writing thread stacks don't use growable mappings (i.e. those
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3008 // creeated with MAP_GROWSDOWN), and aren't marked "[stack]", so this
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3009 // only applies to the main thread.
2469
677234770800 7017193: Small memory leak in get_stack_bounds os::create_stack_guard_pages
dsamersoff
parents: 2302
diff changeset
3010
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3011 // If the (growable) stack mapping already extends beyond the point
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3012 // where we're going to put our guard pages, truncate the mapping at
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3013 // that point by munmap()ping it. This ensures that when we later
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3014 // munmap() the guard pages we don't leave a hole in the stack
12144
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3015 // mapping. This only affects the main/initial thread
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3016
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
3017 bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
12144
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3018
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3019 if (os::Linux::is_initial_thread()) {
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3020 // As we manually grow stack up to bottom inside create_attached_thread(),
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3021 // it's likely that os::Linux::initial_thread_stack_bottom is mapped and
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3022 // we don't need to do anything special.
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3023 // Check it first, before calling heavy function.
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3024 uintptr_t stack_extent = (uintptr_t) os::Linux::initial_thread_stack_bottom();
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3025 unsigned char vec[1];
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3026
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3027 if (mincore((address)stack_extent, os::vm_page_size(), vec) == -1) {
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3028 // Fallback to slow path on all errors, including EAGAIN
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3029 stack_extent = (uintptr_t) get_stack_commited_bottom(
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3030 os::Linux::initial_thread_stack_bottom(),
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3031 (size_t)addr - stack_extent);
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3032 }
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3033
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3034 if (stack_extent < (uintptr_t)addr) {
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3035 ::munmap((void*)stack_extent, (uintptr_t)(addr - stack_extent));
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3036 }
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3037 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3038
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
3039 return os::commit_memory(addr, size, !ExecMem);
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3040 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3041
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3042 // If this is a growable mapping, remove the guard pages entirely by
1750
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
3043 // munmap()ping them. If not, just call uncommit_memory(). This only
c7004d700b49 6978641: Fix for 6929067 introduces additional overhead in thread creation/termination paths
dholmes
parents: 1681
diff changeset
3044 // affects the main/initial thread, but guard against future OS changes
12144
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3045 // It's safe to always unmap guard pages for initial thread because we
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3046 // always place it right after end of the mapped region
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3047
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3048 bool os::remove_stack_guard_pages(char* addr, size_t size) {
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3049 uintptr_t stack_extent, stack_base;
12144
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3050
d8e99408faad 8009062: poor performance of JNI AttachCurrentThread after fix for 7017193
dsamersoff
parents: 12110
diff changeset
3051 if (os::Linux::is_initial_thread()) {
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3052 return ::munmap(addr, size) == 0;
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3053 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3054
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3055 return os::uncommit_memory(addr, size);
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3056 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
3057
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 static address _highest_vm_reserved_address = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3059
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 // If 'fixed' is true, anon_mmap() will attempt to reserve anonymous memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 // at 'requested_addr'. If there are existing memory mappings at the same
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 // location, however, they will be overwritten. If 'fixed' is false,
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 // 'requested_addr' is only treated as a hint, the return value may or
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 // may not start from the requested address. Unlike Linux mmap(), this
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 // function returns NULL to indicate failure.
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 static char* anon_mmap(char* requested_addr, size_t bytes, bool fixed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 char * addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3068 int flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
3069
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS;
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 if (fixed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 assert((uintptr_t)requested_addr % os::Linux::page_size() == 0, "unaligned address");
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 flags |= MAP_FIXED;
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3075
10157
f32b6c267d2e 8012015: Use PROT_NONE when reserving memory
mikael
parents: 9062
diff changeset
3076 // Map reserved/uncommitted pages PROT_NONE so we fail early if we
f32b6c267d2e 8012015: Use PROT_NONE when reserving memory
mikael
parents: 9062
diff changeset
3077 // touch an uncommitted page. Otherwise, the read/write might
f32b6c267d2e 8012015: Use PROT_NONE when reserving memory
mikael
parents: 9062
diff changeset
3078 // succeed if we have enough swap space to back the physical page.
f32b6c267d2e 8012015: Use PROT_NONE when reserving memory
mikael
parents: 9062
diff changeset
3079 addr = (char*)::mmap(requested_addr, bytes, PROT_NONE,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 flags, -1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3081
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 if (addr != MAP_FAILED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 // anon_mmap() should only get called during VM initialization,
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 // don't need lock (actually we can skip locking even it can be called
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 // from multiple threads, because _highest_vm_reserved_address is just a
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 // hint about the upper limit of non-stack memory regions.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 if ((address)addr + bytes > _highest_vm_reserved_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 _highest_vm_reserved_address = (address)addr + bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3091
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 return addr == MAP_FAILED ? NULL : addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3094
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 // Don't update _highest_vm_reserved_address, because there might be memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 // regions above addr + size. If so, releasing a memory region only creates
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 // a hole in the address space, it doesn't help prevent heap-stack collision.
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 static int anon_munmap(char * addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 return ::munmap(addr, size) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3102
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
3103 char* os::pd_reserve_memory(size_t bytes, char* requested_addr,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 size_t alignment_hint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3107
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
3108 bool os::pd_release_memory(char* addr, size_t size) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 return anon_munmap(addr, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3111
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 static address highest_vm_reserved_address() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 return _highest_vm_reserved_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3115
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 static bool linux_mprotect(char* addr, size_t size, int prot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 // Linux wants the mprotect address argument to be page aligned.
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 char* bottom = (char*)align_size_down((intptr_t)addr, os::Linux::page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3119
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 // According to SUSv3, mprotect() should only be used with mappings
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 // established by mmap(), and mmap() always maps whole pages. Unaligned
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 // 'addr' likely indicates problem in the VM (e.g. trying to change
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 // protection of malloc'ed or statically allocated memory). Check the
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 // caller if you hit this assert.
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 assert(addr == bottom, "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3126
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 size = align_size_up(pointer_delta(addr, bottom, 1) + size, os::Linux::page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 return ::mprotect(bottom, size, prot) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3130
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3131 // Set protections specified
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3132 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3133 bool is_committed) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3134 unsigned int p = 0;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3135 switch (prot) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3136 case MEM_PROT_NONE: p = PROT_NONE; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3137 case MEM_PROT_READ: p = PROT_READ; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3138 case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3139 case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3140 default:
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3141 ShouldNotReachHere();
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3142 }
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3143 // is_committed is unused.
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
3144 return linux_mprotect(addr, bytes, p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3146
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 bool os::guard_memory(char* addr, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 return linux_mprotect(addr, size, PROT_NONE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3150
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 bool os::unguard_memory(char* addr, size_t size) {
477
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 462
diff changeset
3152 return linux_mprotect(addr, size, PROT_READ|PROT_WRITE);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3154
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3155 bool os::Linux::transparent_huge_pages_sanity_check(bool warn, size_t page_size) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3156 bool result = false;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3157 void *p = mmap(NULL, page_size * 2, PROT_READ|PROT_WRITE,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3158 MAP_ANONYMOUS|MAP_PRIVATE,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3159 -1, 0);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3160 if (p != MAP_FAILED) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3161 void *aligned_p = align_ptr_up(p, page_size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3162
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3163 result = madvise(aligned_p, page_size, MADV_HUGEPAGE) == 0;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3164
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3165 munmap(p, page_size * 2);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3166 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3167
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3168 if (warn && !result) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3169 warning("TransparentHugePages is not supported by the operating system.");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3170 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3171
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3172 return result;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3173 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3174
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3175 bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3176 bool result = false;
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3177 void *p = mmap(NULL, page_size, PROT_READ|PROT_WRITE,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3178 MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3179 -1, 0);
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3180
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
3181 if (p != MAP_FAILED) {
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3182 // We don't know if this really is a huge page or not.
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3183 FILE *fp = fopen("/proc/self/maps", "r");
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3184 if (fp) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3185 while (!feof(fp)) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3186 char chars[257];
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3187 long x = 0;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3188 if (fgets(chars, sizeof(chars), fp)) {
3358
97b64f73103b 7043564: compile warning and copyright fixes
iveresov
parents: 3318
diff changeset
3189 if (sscanf(chars, "%lx-%*x", &x) == 1
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3190 && x == (long)p) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3191 if (strstr (chars, "hugepage")) {
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3192 result = true;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3193 break;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3194 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3195 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3196 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3197 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3198 fclose(fp);
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3199 }
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3200 munmap(p, page_size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3201 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3202
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3203 if (warn && !result) {
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3204 warning("HugeTLBFS is not supported by the operating system.");
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3205 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3206
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3207 return result;
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3208 }
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3209
2204
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3210 /*
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3211 * Set the coredump_filter bits to include largepages in core dump (bit 6)
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3212 *
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3213 * From the coredump_filter documentation:
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3214 *
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3215 * - (bit 0) anonymous private memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3216 * - (bit 1) anonymous shared memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3217 * - (bit 2) file-backed private memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3218 * - (bit 3) file-backed shared memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3219 * - (bit 4) ELF header pages in file-backed private memory areas (it is
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3220 * effective only if the bit 2 is cleared)
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3221 * - (bit 5) hugetlb private memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3222 * - (bit 6) hugetlb shared memory
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3223 */
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3224 static void set_coredump_filter(void) {
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3225 FILE *f;
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3226 long cdm;
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3227
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3228 if ((f = fopen("/proc/self/coredump_filter", "r+")) == NULL) {
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3229 return;
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3230 }
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3231
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3232 if (fscanf(f, "%lx", &cdm) != 1) {
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3233 fclose(f);
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3234 return;
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3235 }
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3236
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3237 rewind(f);
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3238
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3239 if ((cdm & LARGEPAGES_BIT) == 0) {
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3240 cdm |= LARGEPAGES_BIT;
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3241 fprintf(f, "%#lx", cdm);
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3242 }
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3243
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3244 fclose(f);
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3245 }
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3246
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 // Large page support
a61af66fc99e Initial load
duke
parents:
diff changeset
3248
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 static size_t _large_page_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3250
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3251 size_t os::Linux::find_large_page_size() {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3252 size_t large_page_size = 0;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3253
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3254 // large_page_size on Linux is used to round up heap size. x86 uses either
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3255 // 2M or 4M page, depending on whether PAE (Physical Address Extensions)
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3256 // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3257 // page as large as 256M.
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3258 //
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3259 // Here we try to figure out page size by parsing /proc/meminfo and looking
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3260 // for a line with the following format:
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3261 // Hugepagesize: 2048 kB
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3262 //
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3263 // If we can't determine the value (e.g. /proc is not mounted, or the text
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3264 // format has been changed), we'll use the largest page size supported by
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3265 // the processor.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3266
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
3267 #ifndef ZERO
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3268 large_page_size = IA32_ONLY(4 * M) AMD64_ONLY(2 * M) IA64_ONLY(256 * M) SPARC_ONLY(4 * M)
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3269 ARM_ONLY(2 * M) PPC_ONLY(4 * M);
1010
354d3184f6b2 6890308: integrate zero assembler hotspot changes
never
parents: 763
diff changeset
3270 #endif // ZERO
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3271
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3272 FILE *fp = fopen("/proc/meminfo", "r");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3273 if (fp) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3274 while (!feof(fp)) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3275 int x = 0;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3276 char buf[16];
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3277 if (fscanf(fp, "Hugepagesize: %d", &x) == 1) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3278 if (x && fgets(buf, sizeof(buf), fp) && strcmp(buf, " kB\n") == 0) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3279 large_page_size = x * K;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3280 break;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3281 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3282 } else {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3283 // skip to next line
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3284 for (;;) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3285 int ch = fgetc(fp);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3286 if (ch == EOF || ch == (int)'\n') break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 }
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3290 fclose(fp);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3291 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3292
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3293 if (!FLAG_IS_DEFAULT(LargePageSizeInBytes) && LargePageSizeInBytes != large_page_size) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3294 warning("Setting LargePageSizeInBytes has no effect on this OS. Large page size is "
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3295 SIZE_FORMAT "%s.", byte_size_in_proper_unit(large_page_size),
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3296 proper_unit_for_byte_size(large_page_size));
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3297 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3298
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3299 return large_page_size;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3300 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3301
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3302 size_t os::Linux::setup_large_page_size() {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3303 _large_page_size = Linux::find_large_page_size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3304 const size_t default_page_size = (size_t)Linux::page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3305 if (_large_page_size > default_page_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3306 _page_sizes[0] = _large_page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3307 _page_sizes[1] = default_page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 _page_sizes[2] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 }
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3310
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3311 return _large_page_size;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3312 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3313
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3314 bool os::Linux::setup_large_page_type(size_t page_size) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3315 if (FLAG_IS_DEFAULT(UseHugeTLBFS) &&
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3316 FLAG_IS_DEFAULT(UseSHM) &&
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3317 FLAG_IS_DEFAULT(UseTransparentHugePages)) {
12832
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3318
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3319 // The type of large pages has not been specified by the user.
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3320
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3321 // Try UseHugeTLBFS and then UseSHM.
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3322 UseHugeTLBFS = UseSHM = true;
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3323
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3324 // Don't try UseTransparentHugePages since there are known
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3325 // performance issues with it turned on. This might change in the future.
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3326 UseTransparentHugePages = false;
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3327 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3328
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3329 if (UseTransparentHugePages) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3330 bool warn_on_failure = !FLAG_IS_DEFAULT(UseTransparentHugePages);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3331 if (transparent_huge_pages_sanity_check(warn_on_failure, page_size)) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3332 UseHugeTLBFS = false;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3333 UseSHM = false;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3334 return true;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3335 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3336 UseTransparentHugePages = false;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3337 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3338
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3339 if (UseHugeTLBFS) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3340 bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3341 if (hugetlbfs_sanity_check(warn_on_failure, page_size)) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3342 UseSHM = false;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3343 return true;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3344 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3345 UseHugeTLBFS = false;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3346 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3347
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3348 return UseSHM;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3349 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3350
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3351 void os::large_page_init() {
12832
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3352 if (!UseLargePages &&
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3353 !UseTransparentHugePages &&
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3354 !UseHugeTLBFS &&
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3355 !UseSHM) {
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3356 // Not using large pages.
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3357 return;
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3358 }
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3359
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3360 if (!FLAG_IS_DEFAULT(UseLargePages) && !UseLargePages) {
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3361 // The user explicitly turned off large pages.
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3362 // Ignore the rest of the large pages flags.
263f2c796d6c 8024838: Significant slowdown due to transparent huge pages
stefank
parents: 12252
diff changeset
3363 UseTransparentHugePages = false;
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3364 UseHugeTLBFS = false;
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3365 UseSHM = false;
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3366 return;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3367 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3368
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3369 size_t large_page_size = Linux::setup_large_page_size();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3370 UseLargePages = Linux::setup_large_page_type(large_page_size);
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3371
2204
63d374c54045 7014918: Improve core/minidump handling in Hotspot
ctornqvi
parents: 2193
diff changeset
3372 set_coredump_filter();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3374
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 #ifndef SHM_HUGETLB
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 #define SHM_HUGETLB 04000
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3378
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3379 char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec) {
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
3380 // "exec" is passed in but not used. Creating the shared image for
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
3381 // the code cache doesn't have an SHM_X executable permission to check.
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3382 assert(UseLargePages && UseSHM, "only for SHM large pages");
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3383 assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3384
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3385 if (!is_size_aligned(bytes, os::large_page_size()) || alignment > os::large_page_size()) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3386 return NULL; // Fallback to small pages.
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3387 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3388
a61af66fc99e Initial load
duke
parents:
diff changeset
3389 key_t key = IPC_PRIVATE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 char *addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3391
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 bool warn_on_failure = UseLargePages &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 (!FLAG_IS_DEFAULT(UseLargePages) ||
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3394 !FLAG_IS_DEFAULT(UseSHM) ||
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3395 !FLAG_IS_DEFAULT(LargePageSizeInBytes)
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 );
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 char msg[128];
a61af66fc99e Initial load
duke
parents:
diff changeset
3398
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 // Create a large shared memory region to attach to based on size.
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 // Currently, size is the total size of the heap
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 int shmid = shmget(key, bytes, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 if (shmid == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 // Possible reasons for shmget failure:
a61af66fc99e Initial load
duke
parents:
diff changeset
3404 // 1. shmmax is too small for Java heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
3405 // > check shmmax value: cat /proc/sys/kernel/shmmax
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 // > increase shmmax value: echo "0xffffffff" > /proc/sys/kernel/shmmax
a61af66fc99e Initial load
duke
parents:
diff changeset
3407 // 2. not enough large page memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 // > check available large pages: cat /proc/meminfo
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 // > increase amount of large pages:
a61af66fc99e Initial load
duke
parents:
diff changeset
3410 // echo new_value > /proc/sys/vm/nr_hugepages
a61af66fc99e Initial load
duke
parents:
diff changeset
3411 // Note 1: different Linux may use different name for this property,
a61af66fc99e Initial load
duke
parents:
diff changeset
3412 // e.g. on Redhat AS-3 it is "hugetlb_pool".
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 // Note 2: it's possible there's enough physical memory available but
a61af66fc99e Initial load
duke
parents:
diff changeset
3414 // they are so fragmented after a long run that they can't
a61af66fc99e Initial load
duke
parents:
diff changeset
3415 // coalesce into large pages. Try to reserve large pages when
a61af66fc99e Initial load
duke
parents:
diff changeset
3416 // the system is still "fresh".
a61af66fc99e Initial load
duke
parents:
diff changeset
3417 if (warn_on_failure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3418 jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
3419 warning("%s", msg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3423
a61af66fc99e Initial load
duke
parents:
diff changeset
3424 // attach to the region
1537
79bf863697eb 6951686: Using large pages on Linux prevents zero based compressed oops
kvn
parents: 1500
diff changeset
3425 addr = (char*)shmat(shmid, req_addr, 0);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 int err = errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3427
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 // Remove shmid. If shmat() is successful, the actual shared memory segment
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 // will be deleted when it's detached by shmdt() or when the process
a61af66fc99e Initial load
duke
parents:
diff changeset
3430 // terminates. If shmat() is not successful this will remove the shared
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 // segment immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 shmctl(shmid, IPC_RMID, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3433
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 if ((intptr_t)addr == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 if (warn_on_failure) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
3437 warning("%s", msg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3441
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3442 return addr;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3443 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3444
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3445 static void warn_on_large_pages_failure(char* req_addr, size_t bytes, int error) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3446 assert(error == ENOMEM, "Only expect to fail if no memory is available");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3447
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3448 bool warn_on_failure = UseLargePages &&
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3449 (!FLAG_IS_DEFAULT(UseLargePages) ||
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3450 !FLAG_IS_DEFAULT(UseHugeTLBFS) ||
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3451 !FLAG_IS_DEFAULT(LargePageSizeInBytes));
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3452
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3453 if (warn_on_failure) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3454 char msg[128];
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3455 jio_snprintf(msg, sizeof(msg), "Failed to reserve large pages memory req_addr: "
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3456 PTR_FORMAT " bytes: " SIZE_FORMAT " (errno = %d).", req_addr, bytes, error);
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
3457 warning("%s", msg);
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3458 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3459 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3460
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3461 char* os::Linux::reserve_memory_special_huge_tlbfs_only(size_t bytes, char* req_addr, bool exec) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3462 assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3463 assert(is_size_aligned(bytes, os::large_page_size()), "Unaligned size");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3464 assert(is_ptr_aligned(req_addr, os::large_page_size()), "Unaligned address");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3465
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3466 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3467 char* addr = (char*)::mmap(req_addr, bytes, prot,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3468 MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3469 -1, 0);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3470
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3471 if (addr == MAP_FAILED) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3472 warn_on_large_pages_failure(req_addr, bytes, errno);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3473 return NULL;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3474 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3475
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3476 assert(is_ptr_aligned(addr, os::large_page_size()), "Must be");
8711
6b803ba47588 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 8710
diff changeset
3477
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3480
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3481 char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t alignment, char* req_addr, bool exec) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3482 size_t large_page_size = os::large_page_size();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3483
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3484 assert(bytes >= large_page_size, "Shouldn't allocate large pages for small sizes");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3485
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3486 // Allocate small pages.
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3487
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3488 char* start;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3489 if (req_addr != NULL) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3490 assert(is_ptr_aligned(req_addr, alignment), "Must be");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3491 assert(is_size_aligned(bytes, alignment), "Must be");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3492 start = os::reserve_memory(bytes, req_addr);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3493 assert(start == NULL || start == req_addr, "Must be");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3494 } else {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3495 start = os::reserve_memory_aligned(bytes, alignment);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3496 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3497
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3498 if (start == NULL) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3499 return NULL;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3500 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3501
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3502 assert(is_ptr_aligned(start, alignment), "Must be");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3503
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3504 // os::reserve_memory_special will record this memory area.
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3505 // Need to release it here to prevent overlapping reservations.
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3506 MemTracker::record_virtual_memory_release((address)start, bytes);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3507
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3508 char* end = start + bytes;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3509
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3510 // Find the regions of the allocated chunk that can be promoted to large pages.
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3511 char* lp_start = (char*)align_ptr_up(start, large_page_size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3512 char* lp_end = (char*)align_ptr_down(end, large_page_size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3513
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3514 size_t lp_bytes = lp_end - lp_start;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3515
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3516 assert(is_size_aligned(lp_bytes, large_page_size), "Must be");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3517
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3518 if (lp_bytes == 0) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3519 // The mapped region doesn't even span the start and the end of a large page.
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3520 // Fall back to allocate a non-special area.
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3521 ::munmap(start, end - start);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3522 return NULL;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3523 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3524
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3525 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3526
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3527
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3528 void* result;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3529
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3530 if (start != lp_start) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3531 result = ::mmap(start, lp_start - start, prot,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3532 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3533 -1, 0);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3534 if (result == MAP_FAILED) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3535 ::munmap(lp_start, end - lp_start);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3536 return NULL;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3537 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3538 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3539
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3540 result = ::mmap(lp_start, lp_bytes, prot,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3541 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_HUGETLB,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3542 -1, 0);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3543 if (result == MAP_FAILED) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3544 warn_on_large_pages_failure(req_addr, bytes, errno);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3545 // If the mmap above fails, the large pages region will be unmapped and we
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3546 // have regions before and after with small pages. Release these regions.
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3547 //
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3548 // | mapped | unmapped | mapped |
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3549 // ^ ^ ^ ^
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3550 // start lp_start lp_end end
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3551 //
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3552 ::munmap(start, lp_start - start);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3553 ::munmap(lp_end, end - lp_end);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3554 return NULL;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3555 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3556
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3557 if (lp_end != end) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3558 result = ::mmap(lp_end, end - lp_end, prot,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3559 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3560 -1, 0);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3561 if (result == MAP_FAILED) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3562 ::munmap(start, lp_end - start);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3563 return NULL;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3564 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3565 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3566
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3567 return start;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3568 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3569
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3570 char* os::Linux::reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, char* req_addr, bool exec) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3571 assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3572 assert(is_ptr_aligned(req_addr, alignment), "Must be");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3573 assert(is_power_of_2(alignment), "Must be");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3574 assert(is_power_of_2(os::large_page_size()), "Must be");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3575 assert(bytes >= os::large_page_size(), "Shouldn't allocate large pages for small sizes");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3576
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3577 if (is_size_aligned(bytes, os::large_page_size()) && alignment <= os::large_page_size()) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3578 return reserve_memory_special_huge_tlbfs_only(bytes, req_addr, exec);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3579 } else {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3580 return reserve_memory_special_huge_tlbfs_mixed(bytes, alignment, req_addr, exec);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3581 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3582 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3583
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3584 char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3585 assert(UseLargePages, "only for large pages");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3586
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3587 char* addr;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3588 if (UseSHM) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3589 addr = os::Linux::reserve_memory_special_shm(bytes, alignment, req_addr, exec);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3590 } else {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3591 assert(UseHugeTLBFS, "must be");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3592 addr = os::Linux::reserve_memory_special_huge_tlbfs(bytes, alignment, req_addr, exec);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3593 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3594
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3595 if (addr != NULL) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3596 if (UseNUMAInterleaving) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3597 numa_make_global(addr, bytes);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3598 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3599
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3600 // The memory is committed
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3601 MemTracker::record_virtual_memory_reserve_and_commit((address)addr, bytes, mtNone, CALLER_PC);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3602 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3603
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3604 return addr;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3605 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3606
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3607 bool os::Linux::release_memory_special_shm(char* base, size_t bytes) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3608 // detaching the SHM segment will also delete it, see reserve_memory_special_shm()
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3609 return shmdt(base) == 0;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3610 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3611
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3612 bool os::Linux::release_memory_special_huge_tlbfs(char* base, size_t bytes) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3613 return pd_release_memory(base, bytes);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3614 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3615
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 bool os::release_memory_special(char* base, size_t bytes) {
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3617 assert(UseLargePages, "only for large pages");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3618
10986
1f4355cee9a2 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 10969
diff changeset
3619 MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3620
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3621 bool res;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3622 if (UseSHM) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3623 res = os::Linux::release_memory_special_shm(base, bytes);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3624 } else {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3625 assert(UseHugeTLBFS, "must be");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3626 res = os::Linux::release_memory_special_huge_tlbfs(base, bytes);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3627 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3628
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3629 if (res) {
10986
1f4355cee9a2 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 10969
diff changeset
3630 tkr.record((address)base, bytes);
8711
6b803ba47588 8008257: NMT: assert(new_rec->is_allocation_record()) failed when running with shared memory option
zgu
parents: 8710
diff changeset
3631 } else {
10986
1f4355cee9a2 8013651: NMT: reserve/release sequence id's in incorrect order due to race
zgu
parents: 10969
diff changeset
3632 tkr.discard();
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3633 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3634
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3635 return res;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3637
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 size_t os::large_page_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 return _large_page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3641
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3642 // With SysV SHM the entire memory region must be allocated as shared
3286
139667d9836a 7034464: Support transparent large pages on Linux
iveresov
parents: 2302
diff changeset
3643 // memory.
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3644 // HugeTLBFS allows application to commit large page memory on demand.
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3645 // However, when committing memory with HugeTLBFS fails, the region
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3646 // that was supposed to be committed will lose the old reservation
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3647 // and allow other threads to steal that memory region. Because of this
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3648 // behavior we can't commit HugeTLBFS memory.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 bool os::can_commit_large_page_memory() {
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3650 return UseTransparentHugePages;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3652
79
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 62
diff changeset
3653 bool os::can_execute_large_page_memory() {
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
3654 return UseTransparentHugePages || UseHugeTLBFS;
79
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 62
diff changeset
3655 }
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 62
diff changeset
3656
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3657 // Reserve memory at an arbitrary address, only if that area is
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 // available (and not reserved for something else).
a61af66fc99e Initial load
duke
parents:
diff changeset
3659
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
3660 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 const int max_tries = 10;
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 char* base[max_tries];
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 size_t size[max_tries];
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 const size_t gap = 0x000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
3665
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 // Assert only that the size is a multiple of the page size, since
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 // that's all that mmap requires, and since that's all we really know
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 // about at this low abstraction level. If we need higher alignment,
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 // we can either pass an alignment to this method or verify alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 // in one of the methods further up the call chain. See bug 5044738.
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
a61af66fc99e Initial load
duke
parents:
diff changeset
3672
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 // Repeatedly allocate blocks until the block is allocated at the
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 // right spot. Give up after max_tries. Note that reserve_memory() will
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 // automatically update _highest_vm_reserved_address if the call is
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 // successful. The variable tracks the highest memory address every reserved
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 // by JVM. It is used to detect heap-stack collision if running with
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 // fixed-stack LinuxThreads. Because here we may attempt to reserve more
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 // space than needed, it could confuse the collision detecting code. To
a61af66fc99e Initial load
duke
parents:
diff changeset
3680 // solve the problem, save current _highest_vm_reserved_address and
a61af66fc99e Initial load
duke
parents:
diff changeset
3681 // calculate the correct value before return.
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 address old_highest = _highest_vm_reserved_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
3683
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 // Linux mmap allows caller to pass an address as hint; give it a try first,
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 // if kernel honors the hint then we can return immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 char * addr = anon_mmap(requested_addr, bytes, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 if (addr == requested_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 return requested_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3690
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 if (addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 // mmap() is successful but it fails to reserve at the requested address
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 anon_munmap(addr, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3695
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 for (i = 0; i < max_tries; ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 base[i] = reserve_memory(bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3699
a61af66fc99e Initial load
duke
parents:
diff changeset
3700 if (base[i] != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3701 // Is this the block we wanted?
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 if (base[i] == requested_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 size[i] = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3706
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 // Does this overlap the block we wanted? Give back the overlapped
a61af66fc99e Initial load
duke
parents:
diff changeset
3708 // parts and try again.
a61af66fc99e Initial load
duke
parents:
diff changeset
3709
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 size_t top_overlap = requested_addr + (bytes + gap) - base[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3711 if (top_overlap >= 0 && top_overlap < bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3712 unmap_memory(base[i], top_overlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3713 base[i] += top_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 size[i] = bytes - top_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 size_t bottom_overlap = base[i] + bytes - requested_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3717 if (bottom_overlap >= 0 && bottom_overlap < bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3718 unmap_memory(requested_addr, bottom_overlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3719 size[i] = bytes - bottom_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3721 size[i] = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3726
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 // Give back the unused reserved pieces.
a61af66fc99e Initial load
duke
parents:
diff changeset
3728
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 for (int j = 0; j < i; ++j) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3730 if (base[j] != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3731 unmap_memory(base[j], size[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3734
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 if (i < max_tries) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3736 _highest_vm_reserved_address = MAX2(old_highest, (address)requested_addr + bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 return requested_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3739 _highest_vm_reserved_address = old_highest;
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3742 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3743
a61af66fc99e Initial load
duke
parents:
diff changeset
3744 size_t os::read(int fd, void *buf, unsigned int nBytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 return ::read(fd, buf, nBytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3747
a61af66fc99e Initial load
duke
parents:
diff changeset
3748 // TODO-FIXME: reconcile Solaris' os::sleep with the linux variation.
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 // Solaris uses poll(), linux uses park().
a61af66fc99e Initial load
duke
parents:
diff changeset
3750 // Poll() is likely a better choice, assuming that Thread.interrupt()
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 // generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 // SIGSEGV, see 4355769.
a61af66fc99e Initial load
duke
parents:
diff changeset
3753
a61af66fc99e Initial load
duke
parents:
diff changeset
3754 int os::sleep(Thread* thread, jlong millis, bool interruptible) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3755 assert(thread == Thread::current(), "thread consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3756
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 ParkEvent * const slp = thread->_SleepEvent ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3758 slp->reset() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3759 OrderAccess::fence() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3760
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 if (interruptible) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 jlong prevtime = javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
3763
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3765 if (os::is_interrupted(thread, true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3766 return OS_INTRPT;
a61af66fc99e Initial load
duke
parents:
diff changeset
3767 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3768
a61af66fc99e Initial load
duke
parents:
diff changeset
3769 jlong newtime = javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
3770
a61af66fc99e Initial load
duke
parents:
diff changeset
3771 if (newtime - prevtime < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 // time moving backwards, should only happen if no monotonic clock
a61af66fc99e Initial load
duke
parents:
diff changeset
3773 // not a guarantee() because JVM should not abort on kernel/glibc bugs
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 assert(!Linux::supports_monotonic_clock(), "time moving backwards");
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 } else {
4712
e7dead7e90af 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 4082
diff changeset
3776 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3778
a61af66fc99e Initial load
duke
parents:
diff changeset
3779 if(millis <= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3780 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3782
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 prevtime = newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3784
a61af66fc99e Initial load
duke
parents:
diff changeset
3785 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3786 assert(thread->is_Java_thread(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3787 JavaThread *jt = (JavaThread *) thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
3788 ThreadBlockInVM tbivm(jt);
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
3790
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 jt->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 // cleared by handle_special_suspend_equivalent_condition() or
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 // java_suspend_self() via check_and_wait_while_suspended()
a61af66fc99e Initial load
duke
parents:
diff changeset
3794
a61af66fc99e Initial load
duke
parents:
diff changeset
3795 slp->park(millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
3796
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 jt->check_and_wait_while_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
3799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3800 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3802 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
3803 jlong prevtime = javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
3804
a61af66fc99e Initial load
duke
parents:
diff changeset
3805 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3806 // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 // the 1st iteration ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 jlong newtime = javaTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
3809
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 if (newtime - prevtime < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3811 // time moving backwards, should only happen if no monotonic clock
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 // not a guarantee() because JVM should not abort on kernel/glibc bugs
a61af66fc99e Initial load
duke
parents:
diff changeset
3813 assert(!Linux::supports_monotonic_clock(), "time moving backwards");
a61af66fc99e Initial load
duke
parents:
diff changeset
3814 } else {
4712
e7dead7e90af 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 4082
diff changeset
3815 millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3817
a61af66fc99e Initial load
duke
parents:
diff changeset
3818 if(millis <= 0) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3819
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 prevtime = newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3821 slp->park(millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
3822 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 return OS_OK ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3826
17706
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3827 //
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3828 // Short sleep, direct OS call.
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3829 //
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3830 // Note: certain versions of Linux CFS scheduler (since 2.6.23) do not guarantee
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3831 // sched_yield(2) will actually give up the CPU:
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3832 //
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3833 // * Alone on this pariticular CPU, keeps running.
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3834 // * Before the introduction of "skip_buddy" with "compat_yield" disabled
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3835 // (pre 2.6.39).
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3836 //
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3837 // So calling this with 0 is an alternative.
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3838 //
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3839 void os::naked_short_sleep(jlong ms) {
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3840 struct timespec req;
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3841
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3842 assert(ms < 1000, "Un-interruptable sleep, short time use only");
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3843 req.tv_sec = 0;
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3844 if (ms > 0) {
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3845 req.tv_nsec = (ms % 1000) * 1000000;
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3846 }
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3847 else {
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3848 req.tv_nsec = 1;
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3849 }
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3850
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3851 nanosleep(&req, NULL);
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3852
0e6af9b390af 8028280: ParkEvent leak when running modified runThese which only loads classes
dsimms
parents: 17684
diff changeset
3853 return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3855
a61af66fc99e Initial load
duke
parents:
diff changeset
3856 // Sleep forever; naked call to OS-specific sleep; use with CAUTION
a61af66fc99e Initial load
duke
parents:
diff changeset
3857 void os::infinite_sleep() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 while (true) { // sleep forever ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3859 ::sleep(100); // ... 100 seconds at a time
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3862
a61af66fc99e Initial load
duke
parents:
diff changeset
3863 // Used to convert frequent JVM_Yield() to nops
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 bool os::dont_yield() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3865 return DontYieldALot;
a61af66fc99e Initial load
duke
parents:
diff changeset
3866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3867
a61af66fc99e Initial load
duke
parents:
diff changeset
3868 void os::yield() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3869 sched_yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
3870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3871
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;}
a61af66fc99e Initial load
duke
parents:
diff changeset
3873
a61af66fc99e Initial load
duke
parents:
diff changeset
3874 void os::yield_all(int attempts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3875 // Yields to all threads, including threads with lower priorities
a61af66fc99e Initial load
duke
parents:
diff changeset
3876 // Threads on Linux are all with same priority. The Solaris style
a61af66fc99e Initial load
duke
parents:
diff changeset
3877 // os::yield_all() with nanosleep(1ms) is not necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
3878 sched_yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
3879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3880
a61af66fc99e Initial load
duke
parents:
diff changeset
3881 // Called from the tight loops to possibly influence time-sharing heuristics
a61af66fc99e Initial load
duke
parents:
diff changeset
3882 void os::loop_breaker(int attempts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 os::yield_all(attempts);
a61af66fc99e Initial load
duke
parents:
diff changeset
3884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3885
a61af66fc99e Initial load
duke
parents:
diff changeset
3886 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
3887 // thread priority support
a61af66fc99e Initial load
duke
parents:
diff changeset
3888
a61af66fc99e Initial load
duke
parents:
diff changeset
3889 // Note: Normal Linux applications are run with SCHED_OTHER policy. SCHED_OTHER
a61af66fc99e Initial load
duke
parents:
diff changeset
3890 // only supports dynamic priority, static priority must be zero. For real-time
a61af66fc99e Initial load
duke
parents:
diff changeset
3891 // applications, Linux supports SCHED_RR which allows static priority (1-99).
a61af66fc99e Initial load
duke
parents:
diff changeset
3892 // However, for large multi-threaded applications, SCHED_RR is not only slower
a61af66fc99e Initial load
duke
parents:
diff changeset
3893 // than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out
a61af66fc99e Initial load
duke
parents:
diff changeset
3894 // of 5 runs - Sep 2005).
a61af66fc99e Initial load
duke
parents:
diff changeset
3895 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3896 // The following code actually changes the niceness of kernel-thread/LWP. It
a61af66fc99e Initial load
duke
parents:
diff changeset
3897 // has an assumption that setpriority() only modifies one kernel-thread/LWP,
a61af66fc99e Initial load
duke
parents:
diff changeset
3898 // not the entire user process, and user level threads are 1:1 mapped to kernel
a61af66fc99e Initial load
duke
parents:
diff changeset
3899 // threads. It has always been the case, but could change in the future. For
a61af66fc99e Initial load
duke
parents:
diff changeset
3900 // this reason, the code should not be used as default (ThreadPriorityPolicy=0).
a61af66fc99e Initial load
duke
parents:
diff changeset
3901 // It is only used when ThreadPriorityPolicy=1 and requires root privilege.
a61af66fc99e Initial load
duke
parents:
diff changeset
3902
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3903 int os::java_to_os_priority[CriticalPriority + 1] = {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 19, // 0 Entry should never be used
a61af66fc99e Initial load
duke
parents:
diff changeset
3905
a61af66fc99e Initial load
duke
parents:
diff changeset
3906 4, // 1 MinPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
3907 3, // 2
a61af66fc99e Initial load
duke
parents:
diff changeset
3908 2, // 3
a61af66fc99e Initial load
duke
parents:
diff changeset
3909
a61af66fc99e Initial load
duke
parents:
diff changeset
3910 1, // 4
a61af66fc99e Initial load
duke
parents:
diff changeset
3911 0, // 5 NormPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 -1, // 6
a61af66fc99e Initial load
duke
parents:
diff changeset
3913
a61af66fc99e Initial load
duke
parents:
diff changeset
3914 -2, // 7
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 -3, // 8
a61af66fc99e Initial load
duke
parents:
diff changeset
3916 -4, // 9 NearMaxPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
3917
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3918 -5, // 10 MaxPriority
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3919
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3920 -5 // 11 CriticalPriority
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3921 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3922
a61af66fc99e Initial load
duke
parents:
diff changeset
3923 static int prio_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3924 if (ThreadPriorityPolicy == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3925 // Only root can raise thread priority. Don't allow ThreadPriorityPolicy=1
a61af66fc99e Initial load
duke
parents:
diff changeset
3926 // if effective uid is not root. Perhaps, a more elegant way of doing
a61af66fc99e Initial load
duke
parents:
diff changeset
3927 // this is to test CAP_SYS_NICE capability, but that will require libcap.so
a61af66fc99e Initial load
duke
parents:
diff changeset
3928 if (geteuid() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3929 if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3930 warning("-XX:ThreadPriorityPolicy requires root privilege on Linux");
a61af66fc99e Initial load
duke
parents:
diff changeset
3931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3932 ThreadPriorityPolicy = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3934 }
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3935 if (UseCriticalJavaThreadPriority) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3936 os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3937 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3938 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3940
a61af66fc99e Initial load
duke
parents:
diff changeset
3941 OSReturn os::set_native_priority(Thread* thread, int newpri) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3943
a61af66fc99e Initial load
duke
parents:
diff changeset
3944 int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 return (ret == 0) ? OS_OK : OS_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
3946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3947
a61af66fc99e Initial load
duke
parents:
diff changeset
3948 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 if ( !UseThreadPriorities || ThreadPriorityPolicy == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 *priority_ptr = java_to_os_priority[NormPriority];
a61af66fc99e Initial load
duke
parents:
diff changeset
3951 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3953
a61af66fc99e Initial load
duke
parents:
diff changeset
3954 errno = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3955 *priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
3956 return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR);
a61af66fc99e Initial load
duke
parents:
diff changeset
3957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3958
a61af66fc99e Initial load
duke
parents:
diff changeset
3959 // Hint to the underlying OS that a task switch would not be good.
a61af66fc99e Initial load
duke
parents:
diff changeset
3960 // Void return because it's a hint and can fail.
a61af66fc99e Initial load
duke
parents:
diff changeset
3961 void os::hint_no_preempt() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
3962
a61af66fc99e Initial load
duke
parents:
diff changeset
3963 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
3964 // suspend/resume support
a61af66fc99e Initial load
duke
parents:
diff changeset
3965
a61af66fc99e Initial load
duke
parents:
diff changeset
3966 // the low-level signal-based suspend/resume support is a remnant from the
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 // old VM-suspension that used to be for java-suspension, safepoints etc,
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 // within hotspot. Now there is a single use-case for this:
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 // - calling get_thread_pc() on the VMThread by the flat-profiler task
a61af66fc99e Initial load
duke
parents:
diff changeset
3970 // that runs in the watcher thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
3971 // The remaining code is greatly simplified from the more general suspension
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 // code that used to be used.
a61af66fc99e Initial load
duke
parents:
diff changeset
3973 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 // The protocol is quite simple:
a61af66fc99e Initial load
duke
parents:
diff changeset
3975 // - suspend:
a61af66fc99e Initial load
duke
parents:
diff changeset
3976 // - sends a signal to the target thread
a61af66fc99e Initial load
duke
parents:
diff changeset
3977 // - polls the suspend state of the osthread using a yield loop
a61af66fc99e Initial load
duke
parents:
diff changeset
3978 // - target thread signal handler (SR_handler) sets suspend state
a61af66fc99e Initial load
duke
parents:
diff changeset
3979 // and blocks in sigsuspend until continued
a61af66fc99e Initial load
duke
parents:
diff changeset
3980 // - resume:
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 // - sets target osthread state to continue
a61af66fc99e Initial load
duke
parents:
diff changeset
3982 // - sends signal to end the sigsuspend loop in the SR_handler
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3984 // Note that the SR_lock plays no role in this suspend/resume protocol.
a61af66fc99e Initial load
duke
parents:
diff changeset
3985 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3986
a61af66fc99e Initial load
duke
parents:
diff changeset
3987 static void resume_clear_context(OSThread *osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3988 osthread->set_ucontext(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3989 osthread->set_siginfo(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3991
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 static void suspend_save_context(OSThread *osthread, siginfo_t* siginfo, ucontext_t* context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3993 osthread->set_ucontext(context);
a61af66fc99e Initial load
duke
parents:
diff changeset
3994 osthread->set_siginfo(siginfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
3995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3996
a61af66fc99e Initial load
duke
parents:
diff changeset
3997 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3998 // Handler function invoked when a thread's execution is suspended or
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 // resumed. We have to be careful that only async-safe functions are
a61af66fc99e Initial load
duke
parents:
diff changeset
4000 // called here (Note: most pthread functions are not async safe and
a61af66fc99e Initial load
duke
parents:
diff changeset
4001 // should be avoided.)
a61af66fc99e Initial load
duke
parents:
diff changeset
4002 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 // Note: sigwait() is a more natural fit than sigsuspend() from an
a61af66fc99e Initial load
duke
parents:
diff changeset
4004 // interface point of view, but sigwait() prevents the signal hander
a61af66fc99e Initial load
duke
parents:
diff changeset
4005 // from being run. libpthread would get very confused by not having
a61af66fc99e Initial load
duke
parents:
diff changeset
4006 // its signal handlers run and prevents sigwait()'s use with the
a61af66fc99e Initial load
duke
parents:
diff changeset
4007 // mutex granting granting signal.
a61af66fc99e Initial load
duke
parents:
diff changeset
4008 //
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4009 // Currently only ever called on the VMThread and JavaThreads (PC sampling)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4010 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4011 static void SR_handler(int sig, siginfo_t* siginfo, ucontext_t* context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4012 // Save and restore errno to avoid confusing native code with EINTR
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 // after sigsuspend.
a61af66fc99e Initial load
duke
parents:
diff changeset
4014 int old_errno = errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
4015
a61af66fc99e Initial load
duke
parents:
diff changeset
4016 Thread* thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
4017 OSThread* osthread = thread->osthread();
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4018 assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4019
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4020 os::SuspendResume::State current = osthread->sr.state();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4021 if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4022 suspend_save_context(osthread, siginfo, context);
a61af66fc99e Initial load
duke
parents:
diff changeset
4023
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4024 // attempt to switch the state, we assume we had a SUSPEND_REQUEST
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4025 os::SuspendResume::State state = osthread->sr.suspended();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4026 if (state == os::SuspendResume::SR_SUSPENDED) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4027 sigset_t suspend_set; // signals for sigsuspend()
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4028
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4029 // get current set of blocked signals and unblock resume signal
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4030 pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4031 sigdelset(&suspend_set, SR_signum);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4032
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4033 sr_semaphore.signal();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4034 // wait here until we are resumed
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4035 while (1) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4036 sigsuspend(&suspend_set);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4037
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4038 os::SuspendResume::State result = osthread->sr.running();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4039 if (result == os::SuspendResume::SR_RUNNING) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4040 sr_semaphore.signal();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4041 break;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4042 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4043 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4044
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4045 } else if (state == os::SuspendResume::SR_RUNNING) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4046 // request was cancelled, continue
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4047 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4048 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4049 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4050
a61af66fc99e Initial load
duke
parents:
diff changeset
4051 resume_clear_context(osthread);
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4052 } else if (current == os::SuspendResume::SR_RUNNING) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4053 // request was cancelled, continue
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4054 } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4055 // ignore
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4056 } else {
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4057 // ignore
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4059
a61af66fc99e Initial load
duke
parents:
diff changeset
4060 errno = old_errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
4061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4062
a61af66fc99e Initial load
duke
parents:
diff changeset
4063
a61af66fc99e Initial load
duke
parents:
diff changeset
4064 static int SR_initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4065 struct sigaction act;
a61af66fc99e Initial load
duke
parents:
diff changeset
4066 char *s;
a61af66fc99e Initial load
duke
parents:
diff changeset
4067 /* Get signal number to use for suspend/resume */
a61af66fc99e Initial load
duke
parents:
diff changeset
4068 if ((s = ::getenv("_JAVA_SR_SIGNUM")) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4069 int sig = ::strtol(s, 0, 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
4070 if (sig > 0 || sig < _NSIG) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4071 SR_signum = sig;
a61af66fc99e Initial load
duke
parents:
diff changeset
4072 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4074
a61af66fc99e Initial load
duke
parents:
diff changeset
4075 assert(SR_signum > SIGSEGV && SR_signum > SIGBUS,
a61af66fc99e Initial load
duke
parents:
diff changeset
4076 "SR_signum must be greater than max(SIGSEGV, SIGBUS), see 4355769");
a61af66fc99e Initial load
duke
parents:
diff changeset
4077
a61af66fc99e Initial load
duke
parents:
diff changeset
4078 sigemptyset(&SR_sigset);
a61af66fc99e Initial load
duke
parents:
diff changeset
4079 sigaddset(&SR_sigset, SR_signum);
a61af66fc99e Initial load
duke
parents:
diff changeset
4080
a61af66fc99e Initial load
duke
parents:
diff changeset
4081 /* Set up signal handler for suspend/resume */
a61af66fc99e Initial load
duke
parents:
diff changeset
4082 act.sa_flags = SA_RESTART|SA_SIGINFO;
a61af66fc99e Initial load
duke
parents:
diff changeset
4083 act.sa_handler = (void (*)(int)) SR_handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
4084
a61af66fc99e Initial load
duke
parents:
diff changeset
4085 // SR_signum is blocked by default.
a61af66fc99e Initial load
duke
parents:
diff changeset
4086 // 4528190 - We also need to block pthread restart signal (32 on all
a61af66fc99e Initial load
duke
parents:
diff changeset
4087 // supported Linux platforms). Note that LinuxThreads need to block
a61af66fc99e Initial load
duke
parents:
diff changeset
4088 // this signal for all threads to work properly. So we don't have
a61af66fc99e Initial load
duke
parents:
diff changeset
4089 // to use hard-coded signal number when setting up the mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
4090 pthread_sigmask(SIG_BLOCK, NULL, &act.sa_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
4091
a61af66fc99e Initial load
duke
parents:
diff changeset
4092 if (sigaction(SR_signum, &act, 0) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4093 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4095
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 // Save signal flag
a61af66fc99e Initial load
duke
parents:
diff changeset
4097 os::Linux::set_our_sigflags(SR_signum, act.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
4098 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4100
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4101 static int sr_notify(OSThread* osthread) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4102 int status = pthread_kill(osthread->pthread_id(), SR_signum);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4103 assert_status(status == 0, status, "pthread_kill");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4104 return status;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4105 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4106
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4107 // "Randomly" selected value for how long we want to spin
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4108 // before bailing out on suspending a thread, also how often
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4109 // we send a signal to a thread we want to resume
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4110 static const int RANDOMLY_LARGE_INTEGER = 1000000;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4111 static const int RANDOMLY_LARGE_INTEGER2 = 100;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4112
a61af66fc99e Initial load
duke
parents:
diff changeset
4113 // returns true on success and false on error - really an error is fatal
a61af66fc99e Initial load
duke
parents:
diff changeset
4114 // but this seems the normal response to library errors
a61af66fc99e Initial load
duke
parents:
diff changeset
4115 static bool do_suspend(OSThread* osthread) {
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4116 assert(osthread->sr.is_running(), "thread should be running");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4117 assert(!sr_semaphore.trywait(), "semaphore has invalid state");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4118
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4119 // mark as suspended and send signal
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4120 if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4121 // failed to switch, state wasn't running?
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4122 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4123 return false;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4124 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4125
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4126 if (sr_notify(osthread) != 0) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4127 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4128 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4129
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4130 // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4131 while (true) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4132 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4133 break;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4134 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4135 // timeout
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4136 os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4137 if (cancelled == os::SuspendResume::SR_RUNNING) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4138 return false;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4139 } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4140 // make sure that we consume the signal on the semaphore as well
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4141 sr_semaphore.wait();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4142 break;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4143 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4144 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4145 return false;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4146 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4147 }
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4148 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4149
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4150 guarantee(osthread->sr.is_suspended(), "Must be suspended");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4151 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4153
a61af66fc99e Initial load
duke
parents:
diff changeset
4154 static void do_resume(OSThread* osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4155 assert(osthread->sr.is_suspended(), "thread should be suspended");
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4156 assert(!sr_semaphore.trywait(), "invalid semaphore state");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4157
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4158 if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4159 // failed to switch to WAKEUP_REQUEST
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4160 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4161 return;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4162 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4163
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4164 while (true) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4165 if (sr_notify(osthread) == 0) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4166 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4167 if (osthread->sr.is_running()) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4168 return;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4169 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4170 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4171 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4172 ShouldNotReachHere();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4174 }
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4175
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4176 guarantee(osthread->sr.is_running(), "Must be running!");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4178
a61af66fc99e Initial load
duke
parents:
diff changeset
4179 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
4180 // interrupt support
a61af66fc99e Initial load
duke
parents:
diff changeset
4181
a61af66fc99e Initial load
duke
parents:
diff changeset
4182 void os::interrupt(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4183 assert(Thread::current() == thread || Threads_lock->owned_by_self(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4184 "possibility of dangling Thread pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
4185
a61af66fc99e Initial load
duke
parents:
diff changeset
4186 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4187
a61af66fc99e Initial load
duke
parents:
diff changeset
4188 if (!osthread->interrupted()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4189 osthread->set_interrupted(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4190 // More than one thread can get here with the same value of osthread,
a61af66fc99e Initial load
duke
parents:
diff changeset
4191 // resulting in multiple notifications. We do, however, want the store
a61af66fc99e Initial load
duke
parents:
diff changeset
4192 // to interrupted() to be visible to other threads before we execute unpark().
a61af66fc99e Initial load
duke
parents:
diff changeset
4193 OrderAccess::fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
4194 ParkEvent * const slp = thread->_SleepEvent ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4195 if (slp != NULL) slp->unpark() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4197
a61af66fc99e Initial load
duke
parents:
diff changeset
4198 // For JSR166. Unpark even if interrupt status already was set
a61af66fc99e Initial load
duke
parents:
diff changeset
4199 if (thread->is_Java_thread())
a61af66fc99e Initial load
duke
parents:
diff changeset
4200 ((JavaThread*)thread)->parker()->unpark();
a61af66fc99e Initial load
duke
parents:
diff changeset
4201
a61af66fc99e Initial load
duke
parents:
diff changeset
4202 ParkEvent * ev = thread->_ParkEvent ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4203 if (ev != NULL) ev->unpark() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4204
a61af66fc99e Initial load
duke
parents:
diff changeset
4205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4206
a61af66fc99e Initial load
duke
parents:
diff changeset
4207 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4208 assert(Thread::current() == thread || Threads_lock->owned_by_self(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4209 "possibility of dangling Thread pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
4210
a61af66fc99e Initial load
duke
parents:
diff changeset
4211 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4212
a61af66fc99e Initial load
duke
parents:
diff changeset
4213 bool interrupted = osthread->interrupted();
a61af66fc99e Initial load
duke
parents:
diff changeset
4214
a61af66fc99e Initial load
duke
parents:
diff changeset
4215 if (interrupted && clear_interrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4216 osthread->set_interrupted(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4217 // consider thread->_SleepEvent->reset() ... optional optimization
a61af66fc99e Initial load
duke
parents:
diff changeset
4218 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4219
a61af66fc99e Initial load
duke
parents:
diff changeset
4220 return interrupted;
a61af66fc99e Initial load
duke
parents:
diff changeset
4221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4222
a61af66fc99e Initial load
duke
parents:
diff changeset
4223 ///////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
4224 // signal handling (except suspend/resume)
a61af66fc99e Initial load
duke
parents:
diff changeset
4225
a61af66fc99e Initial load
duke
parents:
diff changeset
4226 // This routine may be used by user applications as a "hook" to catch signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
4227 // The user-defined signal handler must pass unrecognized signals to this
a61af66fc99e Initial load
duke
parents:
diff changeset
4228 // routine, and if it returns true (non-zero), then the signal handler must
a61af66fc99e Initial load
duke
parents:
diff changeset
4229 // return immediately. If the flag "abort_if_unrecognized" is true, then this
a61af66fc99e Initial load
duke
parents:
diff changeset
4230 // routine will never retun false (zero), but instead will execute a VM panic
a61af66fc99e Initial load
duke
parents:
diff changeset
4231 // routine kill the process.
a61af66fc99e Initial load
duke
parents:
diff changeset
4232 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4233 // If this routine returns false, it is OK to call it again. This allows
a61af66fc99e Initial load
duke
parents:
diff changeset
4234 // the user-defined signal handler to perform checks either before or after
a61af66fc99e Initial load
duke
parents:
diff changeset
4235 // the VM performs its own checks. Naturally, the user code would be making
a61af66fc99e Initial load
duke
parents:
diff changeset
4236 // a serious error if it tried to handle an exception (such as a null check
a61af66fc99e Initial load
duke
parents:
diff changeset
4237 // or breakpoint) that the VM was generating for its own correct operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
4238 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4239 // This routine may recognize any of the following kinds of signals:
a61af66fc99e Initial load
duke
parents:
diff changeset
4240 // SIGBUS, SIGSEGV, SIGILL, SIGFPE, SIGQUIT, SIGPIPE, SIGXFSZ, SIGUSR1.
a61af66fc99e Initial load
duke
parents:
diff changeset
4241 // It should be consulted by handlers for any of those signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
4242 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4243 // The caller of this routine must pass in the three arguments supplied
a61af66fc99e Initial load
duke
parents:
diff changeset
4244 // to the function referred to in the "sa_sigaction" (not the "sa_handler")
a61af66fc99e Initial load
duke
parents:
diff changeset
4245 // field of the structure passed to sigaction(). This routine assumes that
a61af66fc99e Initial load
duke
parents:
diff changeset
4246 // the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.
a61af66fc99e Initial load
duke
parents:
diff changeset
4247 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4248 // Note that the VM will print warnings if it detects conflicting signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4249 // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
a61af66fc99e Initial load
duke
parents:
diff changeset
4250 //
2191
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
4251 extern "C" JNIEXPORT int
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4252 JVM_handle_linux_signal(int signo, siginfo_t* siginfo,
a61af66fc99e Initial load
duke
parents:
diff changeset
4253 void* ucontext, int abort_if_unrecognized);
a61af66fc99e Initial load
duke
parents:
diff changeset
4254
a61af66fc99e Initial load
duke
parents:
diff changeset
4255 void signalHandler(int sig, siginfo_t* info, void* uc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4256 assert(info != NULL && uc != NULL, "it must be old kernel");
8067
5cd2fac2ae70 6749267: Signal handler should save/restore errno
hseigel
parents: 7994
diff changeset
4257 int orig_errno = errno; // Preserve errno value over signal handler.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4258 JVM_handle_linux_signal(sig, info, uc, true);
8067
5cd2fac2ae70 6749267: Signal handler should save/restore errno
hseigel
parents: 7994
diff changeset
4259 errno = orig_errno;
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
a61af66fc99e Initial load
duke
parents:
diff changeset
4263 // This boolean allows users to forward their own non-matching signals
a61af66fc99e Initial load
duke
parents:
diff changeset
4264 // to JVM_handle_linux_signal, harmlessly.
a61af66fc99e Initial load
duke
parents:
diff changeset
4265 bool os::Linux::signal_handlers_are_installed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4266
a61af66fc99e Initial load
duke
parents:
diff changeset
4267 // For signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
4268 struct sigaction os::Linux::sigact[MAXSIGNUM];
a61af66fc99e Initial load
duke
parents:
diff changeset
4269 unsigned int os::Linux::sigs = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4270 bool os::Linux::libjsig_is_loaded = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4271 typedef struct sigaction *(*get_signal_t)(int);
a61af66fc99e Initial load
duke
parents:
diff changeset
4272 get_signal_t os::Linux::get_signal_action = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4273
a61af66fc99e Initial load
duke
parents:
diff changeset
4274 struct sigaction* os::Linux::get_chained_signal_action(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4275 struct sigaction *actp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4276
a61af66fc99e Initial load
duke
parents:
diff changeset
4277 if (libjsig_is_loaded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4278 // Retrieve the old signal handler from libjsig
a61af66fc99e Initial load
duke
parents:
diff changeset
4279 actp = (*get_signal_action)(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4281 if (actp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4282 // Retrieve the preinstalled signal handler from jvm
a61af66fc99e Initial load
duke
parents:
diff changeset
4283 actp = get_preinstalled_handler(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4285
a61af66fc99e Initial load
duke
parents:
diff changeset
4286 return actp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4288
a61af66fc99e Initial load
duke
parents:
diff changeset
4289 static bool call_chained_handler(struct sigaction *actp, int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
4290 siginfo_t *siginfo, void *context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4291 // Call the old signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
4292 if (actp->sa_handler == SIG_DFL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4293 // It's more reasonable to let jvm treat it as an unexpected exception
a61af66fc99e Initial load
duke
parents:
diff changeset
4294 // instead of taking the default action.
a61af66fc99e Initial load
duke
parents:
diff changeset
4295 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4296 } else if (actp->sa_handler != SIG_IGN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4297 if ((actp->sa_flags & SA_NODEFER) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4298 // automaticlly block the signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4299 sigaddset(&(actp->sa_mask), sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4301
a61af66fc99e Initial load
duke
parents:
diff changeset
4302 sa_handler_t hand;
a61af66fc99e Initial load
duke
parents:
diff changeset
4303 sa_sigaction_t sa;
a61af66fc99e Initial load
duke
parents:
diff changeset
4304 bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4305 // retrieve the chained handler
a61af66fc99e Initial load
duke
parents:
diff changeset
4306 if (siginfo_flag_set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4307 sa = actp->sa_sigaction;
a61af66fc99e Initial load
duke
parents:
diff changeset
4308 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4309 hand = actp->sa_handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
4310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4311
a61af66fc99e Initial load
duke
parents:
diff changeset
4312 if ((actp->sa_flags & SA_RESETHAND) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4313 actp->sa_handler = SIG_DFL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4315
a61af66fc99e Initial load
duke
parents:
diff changeset
4316 // try to honor the signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
4317 sigset_t oset;
a61af66fc99e Initial load
duke
parents:
diff changeset
4318 pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);
a61af66fc99e Initial load
duke
parents:
diff changeset
4319
a61af66fc99e Initial load
duke
parents:
diff changeset
4320 // call into the chained handler
a61af66fc99e Initial load
duke
parents:
diff changeset
4321 if (siginfo_flag_set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4322 (*sa)(sig, siginfo, context);
a61af66fc99e Initial load
duke
parents:
diff changeset
4323 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4324 (*hand)(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4326
a61af66fc99e Initial load
duke
parents:
diff changeset
4327 // restore the signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
4328 pthread_sigmask(SIG_SETMASK, &oset, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4330 // Tell jvm's signal handler the signal is taken care of.
a61af66fc99e Initial load
duke
parents:
diff changeset
4331 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4333
a61af66fc99e Initial load
duke
parents:
diff changeset
4334 bool os::Linux::chained_handler(int sig, siginfo_t* siginfo, void* context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4335 bool chained = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4336 // signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
4337 if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4338 struct sigaction *actp = get_chained_signal_action(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4339 if (actp != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4340 chained = call_chained_handler(actp, sig, siginfo, context);
a61af66fc99e Initial load
duke
parents:
diff changeset
4341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4342 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4343 return chained;
a61af66fc99e Initial load
duke
parents:
diff changeset
4344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4345
a61af66fc99e Initial load
duke
parents:
diff changeset
4346 struct sigaction* os::Linux::get_preinstalled_handler(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4347 if ((( (unsigned int)1 << sig ) & sigs) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4348 return &sigact[sig];
a61af66fc99e Initial load
duke
parents:
diff changeset
4349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4350 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4352
a61af66fc99e Initial load
duke
parents:
diff changeset
4353 void os::Linux::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4354 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
4355 sigact[sig] = oldAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
4356 sigs |= (unsigned int)1 << sig;
a61af66fc99e Initial load
duke
parents:
diff changeset
4357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4358
a61af66fc99e Initial load
duke
parents:
diff changeset
4359 // for diagnostic
a61af66fc99e Initial load
duke
parents:
diff changeset
4360 int os::Linux::sigflags[MAXSIGNUM];
a61af66fc99e Initial load
duke
parents:
diff changeset
4361
a61af66fc99e Initial load
duke
parents:
diff changeset
4362 int os::Linux::get_our_sigflags(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4363 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
4364 return sigflags[sig];
a61af66fc99e Initial load
duke
parents:
diff changeset
4365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4366
a61af66fc99e Initial load
duke
parents:
diff changeset
4367 void os::Linux::set_our_sigflags(int sig, int flags) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4368 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
4369 sigflags[sig] = flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
4370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4371
a61af66fc99e Initial load
duke
parents:
diff changeset
4372 void os::Linux::set_signal_handler(int sig, bool set_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4373 // Check for overwrite.
a61af66fc99e Initial load
duke
parents:
diff changeset
4374 struct sigaction oldAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
4375 sigaction(sig, (struct sigaction*)NULL, &oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
4376
a61af66fc99e Initial load
duke
parents:
diff changeset
4377 void* oldhand = oldAct.sa_sigaction
a61af66fc99e Initial load
duke
parents:
diff changeset
4378 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
4379 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4380 if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4381 oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4382 oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)signalHandler)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4383 if (AllowUserSignalHandlers || !set_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4384 // Do not overwrite; user takes responsibility to forward to us.
a61af66fc99e Initial load
duke
parents:
diff changeset
4385 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4386 } else if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4387 // save the old handler in jvm
a61af66fc99e Initial load
duke
parents:
diff changeset
4388 save_preinstalled_handler(sig, oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
4389 // libjsig also interposes the sigaction() call below and saves the
a61af66fc99e Initial load
duke
parents:
diff changeset
4390 // old sigaction on it own.
a61af66fc99e Initial load
duke
parents:
diff changeset
4391 } else {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4392 fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4393 "%#lx for signal %d.", (long)oldhand, sig));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4396
a61af66fc99e Initial load
duke
parents:
diff changeset
4397 struct sigaction sigAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
4398 sigfillset(&(sigAct.sa_mask));
a61af66fc99e Initial load
duke
parents:
diff changeset
4399 sigAct.sa_handler = SIG_DFL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4400 if (!set_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4401 sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
a61af66fc99e Initial load
duke
parents:
diff changeset
4402 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4403 sigAct.sa_sigaction = signalHandler;
a61af66fc99e Initial load
duke
parents:
diff changeset
4404 sigAct.sa_flags = SA_SIGINFO|SA_RESTART;
a61af66fc99e Initial load
duke
parents:
diff changeset
4405 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4406 // Save flags, which are set by ours
a61af66fc99e Initial load
duke
parents:
diff changeset
4407 assert(sig > 0 && sig < MAXSIGNUM, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
4408 sigflags[sig] = sigAct.sa_flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
4409
a61af66fc99e Initial load
duke
parents:
diff changeset
4410 int ret = sigaction(sig, &sigAct, &oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
4411 assert(ret == 0, "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
4412
a61af66fc99e Initial load
duke
parents:
diff changeset
4413 void* oldhand2 = oldAct.sa_sigaction
a61af66fc99e Initial load
duke
parents:
diff changeset
4414 ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
4415 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4416 assert(oldhand2 == oldhand, "no concurrent signal handler installation");
a61af66fc99e Initial load
duke
parents:
diff changeset
4417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4418
a61af66fc99e Initial load
duke
parents:
diff changeset
4419 // install signal handlers for signals that HotSpot needs to
a61af66fc99e Initial load
duke
parents:
diff changeset
4420 // handle in order to support Java-level exception handling.
a61af66fc99e Initial load
duke
parents:
diff changeset
4421
a61af66fc99e Initial load
duke
parents:
diff changeset
4422 void os::Linux::install_signal_handlers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4423 if (!signal_handlers_are_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4424 signal_handlers_are_installed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4425
a61af66fc99e Initial load
duke
parents:
diff changeset
4426 // signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
4427 typedef void (*signal_setting_t)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4428 signal_setting_t begin_signal_setting = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4429 signal_setting_t end_signal_setting = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4430 begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4431 dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4432 if (begin_signal_setting != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4433 end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4434 dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4435 get_signal_action = CAST_TO_FN_PTR(get_signal_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4436 dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4437 libjsig_is_loaded = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4438 assert(UseSignalChaining, "should enable signal-chaining");
a61af66fc99e Initial load
duke
parents:
diff changeset
4439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4440 if (libjsig_is_loaded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4441 // Tell libjsig jvm is setting signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4442 (*begin_signal_setting)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4444
a61af66fc99e Initial load
duke
parents:
diff changeset
4445 set_signal_handler(SIGSEGV, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4446 set_signal_handler(SIGPIPE, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4447 set_signal_handler(SIGBUS, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4448 set_signal_handler(SIGILL, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4449 set_signal_handler(SIGFPE, true);
14432
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
4450 #if defined(PPC64)
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
4451 set_signal_handler(SIGTRAP, true);
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
4452 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4453 set_signal_handler(SIGXFSZ, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4454
a61af66fc99e Initial load
duke
parents:
diff changeset
4455 if (libjsig_is_loaded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4456 // Tell libjsig jvm finishes setting signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4457 (*end_signal_setting)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4459
a61af66fc99e Initial load
duke
parents:
diff changeset
4460 // We don't activate signal checker if libjsig is in place, we trust ourselves
3956
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3913
diff changeset
4461 // and if UserSignalHandler is installed all bets are off.
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3913
diff changeset
4462 // Log that signal checking is off only if -verbose:jni is specified.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4463 if (CheckJNICalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4464 if (libjsig_is_loaded) {
3956
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3913
diff changeset
4465 if (PrintJNIResolving) {
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3913
diff changeset
4466 tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3913
diff changeset
4467 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4468 check_signals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4470 if (AllowUserSignalHandlers) {
3956
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3913
diff changeset
4471 if (PrintJNIResolving) {
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3913
diff changeset
4472 tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3913
diff changeset
4473 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4474 check_signals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4475 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4479
a61af66fc99e Initial load
duke
parents:
diff changeset
4480 // This is the fastest way to get thread cpu time on Linux.
a61af66fc99e Initial load
duke
parents:
diff changeset
4481 // Returns cpu time (user+sys) for any thread, not only for current.
a61af66fc99e Initial load
duke
parents:
diff changeset
4482 // POSIX compliant clocks are implemented in the kernels 2.6.16+.
a61af66fc99e Initial load
duke
parents:
diff changeset
4483 // It might work on 2.6.10+ with a special kernel/glibc patch.
a61af66fc99e Initial load
duke
parents:
diff changeset
4484 // For reference, please, see IEEE Std 1003.1-2004:
a61af66fc99e Initial load
duke
parents:
diff changeset
4485 // http://www.unix.org/single_unix_specification
a61af66fc99e Initial load
duke
parents:
diff changeset
4486
a61af66fc99e Initial load
duke
parents:
diff changeset
4487 jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4488 struct timespec tp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4489 int rc = os::Linux::clock_gettime(clockid, &tp);
a61af66fc99e Initial load
duke
parents:
diff changeset
4490 assert(rc == 0, "clock_gettime is expected to return 0 code");
a61af66fc99e Initial load
duke
parents:
diff changeset
4491
4712
e7dead7e90af 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 4082
diff changeset
4492 return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4494
a61af66fc99e Initial load
duke
parents:
diff changeset
4495 /////
a61af66fc99e Initial load
duke
parents:
diff changeset
4496 // glibc on Linux platform uses non-documented flag
a61af66fc99e Initial load
duke
parents:
diff changeset
4497 // to indicate, that some special sort of signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4498 // trampoline is used.
a61af66fc99e Initial load
duke
parents:
diff changeset
4499 // We will never set this flag, and we should
a61af66fc99e Initial load
duke
parents:
diff changeset
4500 // ignore this flag in our diagnostic
a61af66fc99e Initial load
duke
parents:
diff changeset
4501 #ifdef SIGNIFICANT_SIGNAL_MASK
a61af66fc99e Initial load
duke
parents:
diff changeset
4502 #undef SIGNIFICANT_SIGNAL_MASK
a61af66fc99e Initial load
duke
parents:
diff changeset
4503 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4504 #define SIGNIFICANT_SIGNAL_MASK (~0x04000000)
a61af66fc99e Initial load
duke
parents:
diff changeset
4505
a61af66fc99e Initial load
duke
parents:
diff changeset
4506 static const char* get_signal_handler_name(address handler,
a61af66fc99e Initial load
duke
parents:
diff changeset
4507 char* buf, int buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4508 int offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
4509 bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
4510 if (found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4511 // skip directory names
a61af66fc99e Initial load
duke
parents:
diff changeset
4512 const char *p1, *p2;
a61af66fc99e Initial load
duke
parents:
diff changeset
4513 p1 = buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
4514 size_t len = strlen(os::file_separator());
a61af66fc99e Initial load
duke
parents:
diff changeset
4515 while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
a61af66fc99e Initial load
duke
parents:
diff changeset
4516 jio_snprintf(buf, buflen, "%s+0x%x", p1, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
4517 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4518 jio_snprintf(buf, buflen, PTR_FORMAT, handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4520 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
4521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4522
a61af66fc99e Initial load
duke
parents:
diff changeset
4523 static void print_signal_handler(outputStream* st, int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
4524 char* buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4525 struct sigaction sa;
a61af66fc99e Initial load
duke
parents:
diff changeset
4526
a61af66fc99e Initial load
duke
parents:
diff changeset
4527 sigaction(sig, NULL, &sa);
a61af66fc99e Initial load
duke
parents:
diff changeset
4528
a61af66fc99e Initial load
duke
parents:
diff changeset
4529 // See comment for SIGNIFICANT_SIGNAL_MASK define
a61af66fc99e Initial load
duke
parents:
diff changeset
4530 sa.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4531
a61af66fc99e Initial load
duke
parents:
diff changeset
4532 st->print("%s: ", os::exception_name(sig, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
4533
a61af66fc99e Initial load
duke
parents:
diff changeset
4534 address handler = (sa.sa_flags & SA_SIGINFO)
a61af66fc99e Initial load
duke
parents:
diff changeset
4535 ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
4536 : CAST_FROM_FN_PTR(address, sa.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4537
a61af66fc99e Initial load
duke
parents:
diff changeset
4538 if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4539 st->print("SIG_DFL");
a61af66fc99e Initial load
duke
parents:
diff changeset
4540 } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4541 st->print("SIG_IGN");
a61af66fc99e Initial load
duke
parents:
diff changeset
4542 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4543 st->print("[%s]", get_signal_handler_name(handler, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
4544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4545
14410
f42f2e2a1518 8020775: PPC64 (part 12): posix signal printing
goetz
parents: 14405
diff changeset
4546 st->print(", sa_mask[0]=");
f42f2e2a1518 8020775: PPC64 (part 12): posix signal printing
goetz
parents: 14405
diff changeset
4547 os::Posix::print_signal_set_short(st, &sa.sa_mask);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4548
a61af66fc99e Initial load
duke
parents:
diff changeset
4549 address rh = VMError::get_resetted_sighandler(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4550 // May be, handler was resetted by VMError?
a61af66fc99e Initial load
duke
parents:
diff changeset
4551 if(rh != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4552 handler = rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
4553 sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4555
14410
f42f2e2a1518 8020775: PPC64 (part 12): posix signal printing
goetz
parents: 14405
diff changeset
4556 st->print(", sa_flags=");
f42f2e2a1518 8020775: PPC64 (part 12): posix signal printing
goetz
parents: 14405
diff changeset
4557 os::Posix::print_sa_flags(st, sa.sa_flags);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4558
a61af66fc99e Initial load
duke
parents:
diff changeset
4559 // Check: is it our handler?
a61af66fc99e Initial load
duke
parents:
diff changeset
4560 if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
4561 handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4562 // It is our signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
4563 // check for flags, reset system-used one!
a61af66fc99e Initial load
duke
parents:
diff changeset
4564 if((int)sa.sa_flags != os::Linux::get_our_sigflags(sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4565 st->print(
a61af66fc99e Initial load
duke
parents:
diff changeset
4566 ", flags was changed from " PTR32_FORMAT ", consider using jsig library",
a61af66fc99e Initial load
duke
parents:
diff changeset
4567 os::Linux::get_our_sigflags(sig));
a61af66fc99e Initial load
duke
parents:
diff changeset
4568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4570 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4572
a61af66fc99e Initial load
duke
parents:
diff changeset
4573
a61af66fc99e Initial load
duke
parents:
diff changeset
4574 #define DO_SIGNAL_CHECK(sig) \
a61af66fc99e Initial load
duke
parents:
diff changeset
4575 if (!sigismember(&check_signal_done, sig)) \
a61af66fc99e Initial load
duke
parents:
diff changeset
4576 os::Linux::check_signal_handler(sig)
a61af66fc99e Initial load
duke
parents:
diff changeset
4577
a61af66fc99e Initial load
duke
parents:
diff changeset
4578 // This method is a periodic task to check for misbehaving JNI applications
a61af66fc99e Initial load
duke
parents:
diff changeset
4579 // under CheckJNI, we can add any periodic checks here
a61af66fc99e Initial load
duke
parents:
diff changeset
4580
a61af66fc99e Initial load
duke
parents:
diff changeset
4581 void os::run_periodic_checks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4582
a61af66fc99e Initial load
duke
parents:
diff changeset
4583 if (check_signals == false) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4584
a61af66fc99e Initial load
duke
parents:
diff changeset
4585 // SEGV and BUS if overridden could potentially prevent
a61af66fc99e Initial load
duke
parents:
diff changeset
4586 // generation of hs*.log in the event of a crash, debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
4587 // such a case can be very challenging, so we absolutely
a61af66fc99e Initial load
duke
parents:
diff changeset
4588 // check the following for a good measure:
a61af66fc99e Initial load
duke
parents:
diff changeset
4589 DO_SIGNAL_CHECK(SIGSEGV);
a61af66fc99e Initial load
duke
parents:
diff changeset
4590 DO_SIGNAL_CHECK(SIGILL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4591 DO_SIGNAL_CHECK(SIGFPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
4592 DO_SIGNAL_CHECK(SIGBUS);
a61af66fc99e Initial load
duke
parents:
diff changeset
4593 DO_SIGNAL_CHECK(SIGPIPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
4594 DO_SIGNAL_CHECK(SIGXFSZ);
14432
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
4595 #if defined(PPC64)
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
4596 DO_SIGNAL_CHECK(SIGTRAP);
935bf3340572 8028470: PPC64 (part 214): linux: extend signal handler to catch SIGTRAP on ppc64.
goetz
parents: 14422
diff changeset
4597 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4598
a61af66fc99e Initial load
duke
parents:
diff changeset
4599 // ReduceSignalUsage allows the user to override these handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4600 // see comments at the very top and jvm_solaris.h
a61af66fc99e Initial load
duke
parents:
diff changeset
4601 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4602 DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4603 DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4604 DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4605 DO_SIGNAL_CHECK(BREAK_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4607
a61af66fc99e Initial load
duke
parents:
diff changeset
4608 DO_SIGNAL_CHECK(SR_signum);
a61af66fc99e Initial load
duke
parents:
diff changeset
4609 DO_SIGNAL_CHECK(INTERRUPT_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4611
a61af66fc99e Initial load
duke
parents:
diff changeset
4612 typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
a61af66fc99e Initial load
duke
parents:
diff changeset
4613
a61af66fc99e Initial load
duke
parents:
diff changeset
4614 static os_sigaction_t os_sigaction = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4615
a61af66fc99e Initial load
duke
parents:
diff changeset
4616 void os::Linux::check_signal_handler(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4617 char buf[O_BUFLEN];
a61af66fc99e Initial load
duke
parents:
diff changeset
4618 address jvmHandler = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4619
a61af66fc99e Initial load
duke
parents:
diff changeset
4620
a61af66fc99e Initial load
duke
parents:
diff changeset
4621 struct sigaction act;
a61af66fc99e Initial load
duke
parents:
diff changeset
4622 if (os_sigaction == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4623 // only trust the default sigaction, in case it has been interposed
a61af66fc99e Initial load
duke
parents:
diff changeset
4624 os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");
a61af66fc99e Initial load
duke
parents:
diff changeset
4625 if (os_sigaction == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4627
a61af66fc99e Initial load
duke
parents:
diff changeset
4628 os_sigaction(sig, (struct sigaction*)NULL, &act);
a61af66fc99e Initial load
duke
parents:
diff changeset
4629
a61af66fc99e Initial load
duke
parents:
diff changeset
4630
a61af66fc99e Initial load
duke
parents:
diff changeset
4631 act.sa_flags &= SIGNIFICANT_SIGNAL_MASK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4632
a61af66fc99e Initial load
duke
parents:
diff changeset
4633 address thisHandler = (act.sa_flags & SA_SIGINFO)
a61af66fc99e Initial load
duke
parents:
diff changeset
4634 ? CAST_FROM_FN_PTR(address, act.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
4635 : CAST_FROM_FN_PTR(address, act.sa_handler) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4636
a61af66fc99e Initial load
duke
parents:
diff changeset
4637
a61af66fc99e Initial load
duke
parents:
diff changeset
4638 switch(sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4639 case SIGSEGV:
a61af66fc99e Initial load
duke
parents:
diff changeset
4640 case SIGBUS:
a61af66fc99e Initial load
duke
parents:
diff changeset
4641 case SIGFPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
4642 case SIGPIPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
4643 case SIGILL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4644 case SIGXFSZ:
a61af66fc99e Initial load
duke
parents:
diff changeset
4645 jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4646 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4647
a61af66fc99e Initial load
duke
parents:
diff changeset
4648 case SHUTDOWN1_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4649 case SHUTDOWN2_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4650 case SHUTDOWN3_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4651 case BREAK_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4652 jvmHandler = (address)user_handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
4653 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4654
a61af66fc99e Initial load
duke
parents:
diff changeset
4655 case INTERRUPT_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4656 jvmHandler = CAST_FROM_FN_PTR(address, SIG_DFL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4657 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4658
a61af66fc99e Initial load
duke
parents:
diff changeset
4659 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
4660 if (sig == SR_signum) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4661 jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)SR_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4662 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4663 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4665 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4667
a61af66fc99e Initial load
duke
parents:
diff changeset
4668 if (thisHandler != jvmHandler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4669 tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4670 tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4671 tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4672 // No need to check this sig any longer
a61af66fc99e Initial load
duke
parents:
diff changeset
4673 sigaddset(&check_signal_done, sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4674 } 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
4675 tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4676 tty->print("expected:" PTR32_FORMAT, os::Linux::get_our_sigflags(sig));
a61af66fc99e Initial load
duke
parents:
diff changeset
4677 tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
4678 // No need to check this sig any longer
a61af66fc99e Initial load
duke
parents:
diff changeset
4679 sigaddset(&check_signal_done, sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4681
a61af66fc99e Initial load
duke
parents:
diff changeset
4682 // Dump all the signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4683 if (sigismember(&check_signal_done, sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4684 print_signal_handlers(tty, buf, O_BUFLEN);
a61af66fc99e Initial load
duke
parents:
diff changeset
4685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4687
a61af66fc99e Initial load
duke
parents:
diff changeset
4688 extern void report_error(char* file_name, int line_no, char* title, char* format, ...);
a61af66fc99e Initial load
duke
parents:
diff changeset
4689
a61af66fc99e Initial load
duke
parents:
diff changeset
4690 extern bool signal_name(int signo, char* buf, size_t len);
a61af66fc99e Initial load
duke
parents:
diff changeset
4691
a61af66fc99e Initial load
duke
parents:
diff changeset
4692 const char* os::exception_name(int exception_code, char* buf, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4693 if (0 < exception_code && exception_code <= SIGRTMAX) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4694 // signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4695 if (!signal_name(exception_code, buf, size)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4696 jio_snprintf(buf, size, "SIG%d", exception_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
4697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4698 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
4699 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4700 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4703
a61af66fc99e Initial load
duke
parents:
diff changeset
4704 // this is called _before_ the most of global arguments have been parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
4705 void os::init(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4706 char dummy; /* used to get a guess on initial stack address */
a61af66fc99e Initial load
duke
parents:
diff changeset
4707 // first_hrtime = gethrtime();
a61af66fc99e Initial load
duke
parents:
diff changeset
4708
a61af66fc99e Initial load
duke
parents:
diff changeset
4709 // With LinuxThreads the JavaMain thread pid (primordial thread)
a61af66fc99e Initial load
duke
parents:
diff changeset
4710 // is different than the pid of the java launcher thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
4711 // So, on Linux, the launcher thread pid is passed to the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
4712 // via the sun.java.launcher.pid property.
a61af66fc99e Initial load
duke
parents:
diff changeset
4713 // Use this property instead of getpid() if it was correctly passed.
a61af66fc99e Initial load
duke
parents:
diff changeset
4714 // See bug 6351349.
a61af66fc99e Initial load
duke
parents:
diff changeset
4715 pid_t java_launcher_pid = (pid_t) Arguments::sun_java_launcher_pid();
a61af66fc99e Initial load
duke
parents:
diff changeset
4716
a61af66fc99e Initial load
duke
parents:
diff changeset
4717 _initial_pid = (java_launcher_pid > 0) ? java_launcher_pid : getpid();
a61af66fc99e Initial load
duke
parents:
diff changeset
4718
a61af66fc99e Initial load
duke
parents:
diff changeset
4719 clock_tics_per_sec = sysconf(_SC_CLK_TCK);
a61af66fc99e Initial load
duke
parents:
diff changeset
4720
a61af66fc99e Initial load
duke
parents:
diff changeset
4721 init_random(1234567);
a61af66fc99e Initial load
duke
parents:
diff changeset
4722
a61af66fc99e Initial load
duke
parents:
diff changeset
4723 ThreadCritical::initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
4724
a61af66fc99e Initial load
duke
parents:
diff changeset
4725 Linux::set_page_size(sysconf(_SC_PAGESIZE));
a61af66fc99e Initial load
duke
parents:
diff changeset
4726 if (Linux::page_size() == -1) {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4727 fatal(err_msg("os_linux.cpp: os::init: sysconf failed (%s)",
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4728 strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4730 init_page_sizes((size_t) Linux::page_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
4731
a61af66fc99e Initial load
duke
parents:
diff changeset
4732 Linux::initialize_system_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
4733
a61af66fc99e Initial load
duke
parents:
diff changeset
4734 // main_thread points to the aboriginal thread
a61af66fc99e Initial load
duke
parents:
diff changeset
4735 Linux::_main_thread = pthread_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
4736
a61af66fc99e Initial load
duke
parents:
diff changeset
4737 Linux::clock_init();
12997
e4f478e7781b 8027294: Prepare hotspot for non TOD based uptime counter
jbachorik
parents: 12840
diff changeset
4738 initial_time_count = javaTimeNanos();
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4739
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4740 // pthread_condattr initialization for monotonic clock
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4741 int status;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4742 pthread_condattr_t* _condattr = os::Linux::condAttr();
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4743 if ((status = pthread_condattr_init(_condattr)) != 0) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4744 fatal(err_msg("pthread_condattr_init: %s", strerror(status)));
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4745 }
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4746 // Only set the clock if CLOCK_MONOTONIC is available
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4747 if (Linux::supports_monotonic_clock()) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4748 if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4749 if (status == EINVAL) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4750 warning("Unable to use monotonic clock with relative timed-waits" \
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4751 " - changes to the time-of-day clock may have adverse affects");
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4752 } else {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4753 fatal(err_msg("pthread_condattr_setclock: %s", strerror(status)));
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4754 }
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4755 }
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4756 }
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4757 // else it defaults to CLOCK_REALTIME
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
4758
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
4759 pthread_mutex_init(&dl_mutex, NULL);
10164
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4760
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4761 // If the pagesize of the VM is greater than 8K determine the appropriate
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4762 // number of initial guard pages. The user can change this with the
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4763 // command line arguments, if needed.
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4764 if (vm_page_size() > (int)Linux::vm_default_page_size()) {
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4765 StackYellowPages = 1;
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4766 StackRedPages = 1;
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4767 StackShadowPages = round_to((StackShadowPages*Linux::vm_default_page_size()), vm_page_size()) / vm_page_size();
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4768 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4770
a61af66fc99e Initial load
duke
parents:
diff changeset
4771 // To install functions for atexit system call
a61af66fc99e Initial load
duke
parents:
diff changeset
4772 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
4773 static void perfMemory_exit_helper() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4774 perfMemory_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
4775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4777
a61af66fc99e Initial load
duke
parents:
diff changeset
4778 // this is called _after_ the global arguments have been parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
4779 jint os::init_2(void)
a61af66fc99e Initial load
duke
parents:
diff changeset
4780 {
a61af66fc99e Initial load
duke
parents:
diff changeset
4781 Linux::fast_thread_clock_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4782
a61af66fc99e Initial load
duke
parents:
diff changeset
4783 // Allocate a single page and mark it as readable for safepoint polling
a61af66fc99e Initial load
duke
parents:
diff changeset
4784 address polling_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4785 guarantee( polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page" );
a61af66fc99e Initial load
duke
parents:
diff changeset
4786
a61af66fc99e Initial load
duke
parents:
diff changeset
4787 os::set_polling_page( polling_page );
a61af66fc99e Initial load
duke
parents:
diff changeset
4788
a61af66fc99e Initial load
duke
parents:
diff changeset
4789 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
4790 if(Verbose && PrintMiscellaneous)
a61af66fc99e Initial load
duke
parents:
diff changeset
4791 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
a61af66fc99e Initial load
duke
parents:
diff changeset
4792 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4793
a61af66fc99e Initial load
duke
parents:
diff changeset
4794 if (!UseMembar) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4795 address mem_serialize_page = (address) ::mmap(NULL, Linux::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
4796 guarantee( mem_serialize_page != MAP_FAILED, "mmap Failed for memory serialize page");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4797 os::set_memory_serialize_page( mem_serialize_page );
a61af66fc99e Initial load
duke
parents:
diff changeset
4798
a61af66fc99e Initial load
duke
parents:
diff changeset
4799 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
4800 if(Verbose && PrintMiscellaneous)
a61af66fc99e Initial load
duke
parents:
diff changeset
4801 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
a61af66fc99e Initial load
duke
parents:
diff changeset
4802 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4804
a61af66fc99e Initial load
duke
parents:
diff changeset
4805 // initialize suspend/resume support - must do this before signal_sets_init()
a61af66fc99e Initial load
duke
parents:
diff changeset
4806 if (SR_initialize() != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4807 perror("SR_initialize failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
4808 return JNI_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
4809 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4810
a61af66fc99e Initial load
duke
parents:
diff changeset
4811 Linux::signal_sets_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4812 Linux::install_signal_handlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
4813
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4814 // Check minimum allowable stack size for thread creation and to initialize
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4815 // the java system classes, including StackOverflowError - depends on page
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4816 // size. Add a page for compiler2 recursion in main thread.
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4817 // Add in 2*BytesPerWord times page size to account for VM stack during
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4818 // class initialization depending on 32 or 64 bit VM.
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4819 os::Linux::min_stack_allowed = MAX2(os::Linux::min_stack_allowed,
10164
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4820 (size_t)(StackYellowPages+StackRedPages+StackShadowPages) * Linux::page_size() +
b4081e9714ec 8013398: Adjust number of stack guard pages on systems with large memory page size
vladidan
parents: 10157
diff changeset
4821 (2*BytesPerWord COMPILER2_PRESENT(+1)) * Linux::vm_default_page_size());
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4822
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4823 size_t threadStackSizeInBytes = ThreadStackSize * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
4824 if (threadStackSizeInBytes != 0 &&
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4825 threadStackSizeInBytes < os::Linux::min_stack_allowed) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4826 tty->print_cr("\nThe stack size specified is too small, "
a61af66fc99e Initial load
duke
parents:
diff changeset
4827 "Specify at least %dk",
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
4828 os::Linux::min_stack_allowed/ K);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4829 return JNI_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
4830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4831
a61af66fc99e Initial load
duke
parents:
diff changeset
4832 // Make the stack size a multiple of the page size so that
a61af66fc99e Initial load
duke
parents:
diff changeset
4833 // the yellow/red zones can be guarded.
a61af66fc99e Initial load
duke
parents:
diff changeset
4834 JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
4835 vm_page_size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
4836
a61af66fc99e Initial load
duke
parents:
diff changeset
4837 Linux::capture_initial_stack(JavaThread::stack_size_at_create());
a61af66fc99e Initial load
duke
parents:
diff changeset
4838
12313
899ecf76b570 8023956: Provide a work-around to broken Linux 32 bit "Exec Shield" using CS for NX emulation (crashing with SI_KERNEL)
dsimms
parents: 12252
diff changeset
4839 #if defined(IA32)
899ecf76b570 8023956: Provide a work-around to broken Linux 32 bit "Exec Shield" using CS for NX emulation (crashing with SI_KERNEL)
dsimms
parents: 12252
diff changeset
4840 workaround_expand_exec_shield_cs_limit();
899ecf76b570 8023956: Provide a work-around to broken Linux 32 bit "Exec Shield" using CS for NX emulation (crashing with SI_KERNEL)
dsimms
parents: 12252
diff changeset
4841 #endif
899ecf76b570 8023956: Provide a work-around to broken Linux 32 bit "Exec Shield" using CS for NX emulation (crashing with SI_KERNEL)
dsimms
parents: 12252
diff changeset
4842
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4843 Linux::libpthread_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4844 if (PrintMiscellaneous && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4845 tty->print_cr("[HotSpot is running with %s, %s(%s)]\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4846 Linux::glibc_version(), Linux::libpthread_version(),
a61af66fc99e Initial load
duke
parents:
diff changeset
4847 Linux::is_floating_stack() ? "floating stack" : "fixed stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
4848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4849
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
4850 if (UseNUMA) {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4851 if (!Linux::libnuma_init()) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4852 UseNUMA = false;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4853 } else {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4854 if ((Linux::numa_max_node() < 1)) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4855 // There's only one node(they start from 0), disable NUMA.
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4856 UseNUMA = false;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4857 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4858 }
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
4859 // With SHM and HugeTLBFS large pages we cannot uncommit a page, so there's no way
3292
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4860 // we can make the adaptive lgrp chunk resizing work. If the user specified
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
4861 // both UseNUMA and UseLargePages (or UseSHM/UseHugeTLBFS) on the command line - warn and
3292
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4862 // disable adaptive resizing.
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
4863 if (UseNUMA && UseLargePages && !can_commit_large_page_memory()) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
4864 if (FLAG_IS_DEFAULT(UseNUMA)) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
4865 UseNUMA = false;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
4866 } else {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
4867 if (FLAG_IS_DEFAULT(UseLargePages) &&
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
4868 FLAG_IS_DEFAULT(UseSHM) &&
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
4869 FLAG_IS_DEFAULT(UseHugeTLBFS)) {
3292
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4870 UseLargePages = false;
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4871 } else {
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
4872 warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing");
3292
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4873 UseAdaptiveSizePolicy = false;
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4874 UseAdaptiveNUMAChunkSizing = false;
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4875 }
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4876 }
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 3290
diff changeset
4877 }
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4878 if (!UseNUMA && ForceNUMA) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4879 UseNUMA = true;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 356
diff changeset
4880 }
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
4881 }
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 79
diff changeset
4882
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4883 if (MaxFDLimit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4884 // set the number of file descriptors to max. print out error
a61af66fc99e Initial load
duke
parents:
diff changeset
4885 // if getrlimit/setrlimit fails but continue regardless.
a61af66fc99e Initial load
duke
parents:
diff changeset
4886 struct rlimit nbr_files;
a61af66fc99e Initial load
duke
parents:
diff changeset
4887 int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
a61af66fc99e Initial load
duke
parents:
diff changeset
4888 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4889 if (PrintMiscellaneous && (Verbose || WizardMode))
a61af66fc99e Initial load
duke
parents:
diff changeset
4890 perror("os::init_2 getrlimit failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
4891 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4892 nbr_files.rlim_cur = nbr_files.rlim_max;
a61af66fc99e Initial load
duke
parents:
diff changeset
4893 status = setrlimit(RLIMIT_NOFILE, &nbr_files);
a61af66fc99e Initial load
duke
parents:
diff changeset
4894 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4895 if (PrintMiscellaneous && (Verbose || WizardMode))
a61af66fc99e Initial load
duke
parents:
diff changeset
4896 perror("os::init_2 setrlimit failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
4897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4900
a61af66fc99e Initial load
duke
parents:
diff changeset
4901 // Initialize lock used to serialize thread creation (see os::create_thread)
a61af66fc99e Initial load
duke
parents:
diff changeset
4902 Linux::set_createThread_lock(new Mutex(Mutex::leaf, "createThread_lock", false));
a61af66fc99e Initial load
duke
parents:
diff changeset
4903
a61af66fc99e Initial load
duke
parents:
diff changeset
4904 // at-exit methods are called in the reverse order of their registration.
a61af66fc99e Initial load
duke
parents:
diff changeset
4905 // atexit functions are called on return from main or as a result of a
a61af66fc99e Initial load
duke
parents:
diff changeset
4906 // call to exit(3C). There can be only 32 of these functions registered
a61af66fc99e Initial load
duke
parents:
diff changeset
4907 // and atexit() does not set errno.
a61af66fc99e Initial load
duke
parents:
diff changeset
4908
a61af66fc99e Initial load
duke
parents:
diff changeset
4909 if (PerfAllowAtExitRegistration) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4910 // only register atexit functions if PerfAllowAtExitRegistration is set.
a61af66fc99e Initial load
duke
parents:
diff changeset
4911 // atexit functions can be delayed until process exit time, which
a61af66fc99e Initial load
duke
parents:
diff changeset
4912 // can be problematic for embedded VM situations. Embedded VMs should
a61af66fc99e Initial load
duke
parents:
diff changeset
4913 // call DestroyJavaVM() to assure that VM resources are released.
a61af66fc99e Initial load
duke
parents:
diff changeset
4914
a61af66fc99e Initial load
duke
parents:
diff changeset
4915 // note: perfMemory_exit_helper atexit function may be removed in
a61af66fc99e Initial load
duke
parents:
diff changeset
4916 // the future if the appropriate cleanup code can be added to the
a61af66fc99e Initial load
duke
parents:
diff changeset
4917 // VM_Exit VMOperation's doit method.
a61af66fc99e Initial load
duke
parents:
diff changeset
4918 if (atexit(perfMemory_exit_helper) != 0) {
14391
d2907f74462e 8016586: PPC64 (part 3): basic changes for PPC64
goetz
parents: 14390
diff changeset
4919 warning("os::init_2 atexit(perfMemory_exit_helper) failed");
0
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 // initialize thread priority policy
a61af66fc99e Initial load
duke
parents:
diff changeset
4924 prio_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4925
a61af66fc99e Initial load
duke
parents:
diff changeset
4926 return JNI_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4928
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4929 // this is called at the end of vm_initialization
14391
d2907f74462e 8016586: PPC64 (part 3): basic changes for PPC64
goetz
parents: 14390
diff changeset
4930 void os::init_3(void) {
3802
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
4931 #ifdef JAVASE_EMBEDDED
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
4932 // Start the MemNotifyThread
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
4933 if (LowMemoryProtection) {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
4934 MemNotifyThread::start();
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
4935 }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
4936 return;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
4937 #endif
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
4938 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
4939
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4940 // Mark the polling page as unreadable
a61af66fc99e Initial load
duke
parents:
diff changeset
4941 void os::make_polling_page_unreadable(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4942 if( !guard_memory((char*)_polling_page, Linux::page_size()) )
a61af66fc99e Initial load
duke
parents:
diff changeset
4943 fatal("Could not disable polling page");
a61af66fc99e Initial load
duke
parents:
diff changeset
4944 };
a61af66fc99e Initial load
duke
parents:
diff changeset
4945
a61af66fc99e Initial load
duke
parents:
diff changeset
4946 // Mark the polling page as readable
a61af66fc99e Initial load
duke
parents:
diff changeset
4947 void os::make_polling_page_readable(void) {
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
4948 if( !linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4949 fatal("Could not enable polling page");
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 235
diff changeset
4950 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4951 };
a61af66fc99e Initial load
duke
parents:
diff changeset
4952
a61af66fc99e Initial load
duke
parents:
diff changeset
4953 int os::active_processor_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4954 // Linux doesn't yet have a (official) notion of processor sets,
a61af66fc99e Initial load
duke
parents:
diff changeset
4955 // so just return the number of online processors.
a61af66fc99e Initial load
duke
parents:
diff changeset
4956 int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
a61af66fc99e Initial load
duke
parents:
diff changeset
4957 assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
4958 return online_cpus;
a61af66fc99e Initial load
duke
parents:
diff changeset
4959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4960
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3966
diff changeset
4961 void os::set_native_thread_name(const char *name) {
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3966
diff changeset
4962 // Not yet implemented.
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3966
diff changeset
4963 return;
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3966
diff changeset
4964 }
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3966
diff changeset
4965
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4966 bool os::distribute_processes(uint length, uint* distribution) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4967 // Not yet implemented.
a61af66fc99e Initial load
duke
parents:
diff changeset
4968 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4969 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4970
a61af66fc99e Initial load
duke
parents:
diff changeset
4971 bool os::bind_to_processor(uint processor_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4972 // Not yet implemented.
a61af66fc99e Initial load
duke
parents:
diff changeset
4973 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4975
a61af66fc99e Initial load
duke
parents:
diff changeset
4976 ///
a61af66fc99e Initial load
duke
parents:
diff changeset
4977
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4978 void os::SuspendedThreadTask::internal_do_task() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4979 if (do_suspend(_thread->osthread())) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4980 SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4981 do_task(context);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4982 do_resume(_thread->osthread());
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4983 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4984 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4985
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4986 class PcFetcher : public os::SuspendedThreadTask {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4987 public:
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4988 PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4989 ExtendedPC result();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4990 protected:
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4991 void do_task(const os::SuspendedThreadTaskContext& context);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4992 private:
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4993 ExtendedPC _epc;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4994 };
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4995
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4996 ExtendedPC PcFetcher::result() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4997 guarantee(is_done(), "task is not done yet.");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4998 return _epc;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
4999 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5000
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5001 void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5002 Thread* thread = context.thread();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5003 OSThread* osthread = thread->osthread();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5004 if (osthread->ucontext() != NULL) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5005 _epc = os::Linux::ucontext_get_pc((ucontext_t *) context.ucontext());
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5006 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5007 // NULL context is unexpected, double-check this is the VMThread
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5008 guarantee(thread->is_VM_thread(), "can only be called for VMThread");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5009 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5010 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5011
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5012 // Suspends the target using the signal mechanism and then grabs the PC before
a61af66fc99e Initial load
duke
parents:
diff changeset
5013 // resuming the target. Used by the flat-profiler only
a61af66fc99e Initial load
duke
parents:
diff changeset
5014 ExtendedPC os::get_thread_pc(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5015 // Make sure that it is called by the watcher for the VMThread
a61af66fc99e Initial load
duke
parents:
diff changeset
5016 assert(Thread::current()->is_Watcher_thread(), "Must be watcher");
a61af66fc99e Initial load
duke
parents:
diff changeset
5017 assert(thread->is_VM_thread(), "Can only be called for VMThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
5018
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5019 PcFetcher fetcher(thread);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5020 fetcher.run();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
5021 return fetcher.result();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5023
a61af66fc99e Initial load
duke
parents:
diff changeset
5024 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
5025 {
a61af66fc99e Initial load
duke
parents:
diff changeset
5026 if (is_NPTL()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5027 return pthread_cond_timedwait(_cond, _mutex, _abstime);
a61af66fc99e Initial load
duke
parents:
diff changeset
5028 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5029 // 6292965: LinuxThreads pthread_cond_timedwait() resets FPU control
a61af66fc99e Initial load
duke
parents:
diff changeset
5030 // word back to default 64bit precision if condvar is signaled. Java
a61af66fc99e Initial load
duke
parents:
diff changeset
5031 // wants 53bit precision. Save and restore current value.
a61af66fc99e Initial load
duke
parents:
diff changeset
5032 int fpu = get_fpu_control_word();
a61af66fc99e Initial load
duke
parents:
diff changeset
5033 int status = pthread_cond_timedwait(_cond, _mutex, _abstime);
a61af66fc99e Initial load
duke
parents:
diff changeset
5034 set_fpu_control_word(fpu);
a61af66fc99e Initial load
duke
parents:
diff changeset
5035 return status;
a61af66fc99e Initial load
duke
parents:
diff changeset
5036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5038
a61af66fc99e Initial load
duke
parents:
diff changeset
5039 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
5040 // debug support
a61af66fc99e Initial load
duke
parents:
diff changeset
5041
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5042 bool os::find(address addr, outputStream* st) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5043 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
5044 memset(&dlinfo, 0, sizeof(dlinfo));
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5045 if (dladdr(addr, &dlinfo) != 0) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5046 st->print(PTR_FORMAT ": ", addr);
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5047 if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5048 st->print("%s+%#x", dlinfo.dli_sname,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5049 addr - (intptr_t)dlinfo.dli_saddr);
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5050 } else if (dlinfo.dli_fbase != NULL) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5051 st->print("<offset %#x>", addr - (intptr_t)dlinfo.dli_fbase);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5052 } else {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5053 st->print("<absolute address>");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5054 }
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5055 if (dlinfo.dli_fname != NULL) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5056 st->print(" in %s", dlinfo.dli_fname);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5057 }
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5058 if (dlinfo.dli_fbase != NULL) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5059 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5060 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5061 st->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5062
a61af66fc99e Initial load
duke
parents:
diff changeset
5063 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5064 // decode some bytes around the PC
9060
cc32ccaaf47f 8003310: Enable -Wunused-function when compiling with gcc
mikael
parents: 9059
diff changeset
5065 address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size());
cc32ccaaf47f 8003310: Enable -Wunused-function when compiling with gcc
mikael
parents: 9059
diff changeset
5066 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5067 address lowest = (address) dlinfo.dli_sname;
a61af66fc99e Initial load
duke
parents:
diff changeset
5068 if (!lowest) lowest = (address) dlinfo.dli_fbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
5069 if (begin < lowest) begin = lowest;
a61af66fc99e Initial load
duke
parents:
diff changeset
5070 Dl_info dlinfo2;
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5071 if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5072 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
a61af66fc99e Initial load
duke
parents:
diff changeset
5073 end = (address) dlinfo2.dli_saddr;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5074 Disassembler::decode(begin, end, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5076 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5078 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5080
a61af66fc99e Initial load
duke
parents:
diff changeset
5081 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
5082 // misc
a61af66fc99e Initial load
duke
parents:
diff changeset
5083
a61af66fc99e Initial load
duke
parents:
diff changeset
5084 // This does not do anything on Linux. This is basically a hook for being
a61af66fc99e Initial load
duke
parents:
diff changeset
5085 // able to use structured exception handling (thread-local exception filters)
a61af66fc99e Initial load
duke
parents:
diff changeset
5086 // on, e.g., Win32.
a61af66fc99e Initial load
duke
parents:
diff changeset
5087 void
a61af66fc99e Initial load
duke
parents:
diff changeset
5088 os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method,
a61af66fc99e Initial load
duke
parents:
diff changeset
5089 JavaCallArguments* args, Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5090 f(value, method, args, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
5091 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5092
a61af66fc99e Initial load
duke
parents:
diff changeset
5093 void os::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5094 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5095
a61af66fc99e Initial load
duke
parents:
diff changeset
5096 int os::message_box(const char* title, const char* message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5097 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
5098 fdStream err(defaultStream::error_fd());
a61af66fc99e Initial load
duke
parents:
diff changeset
5099 for (i = 0; i < 78; i++) err.print_raw("=");
a61af66fc99e Initial load
duke
parents:
diff changeset
5100 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
5101 err.print_raw_cr(title);
a61af66fc99e Initial load
duke
parents:
diff changeset
5102 for (i = 0; i < 78; i++) err.print_raw("-");
a61af66fc99e Initial load
duke
parents:
diff changeset
5103 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
5104 err.print_raw_cr(message);
a61af66fc99e Initial load
duke
parents:
diff changeset
5105 for (i = 0; i < 78; i++) err.print_raw("=");
a61af66fc99e Initial load
duke
parents:
diff changeset
5106 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
5107
a61af66fc99e Initial load
duke
parents:
diff changeset
5108 char buf[16];
a61af66fc99e Initial load
duke
parents:
diff changeset
5109 // Prevent process from exiting upon "read error" without consuming all CPU
a61af66fc99e Initial load
duke
parents:
diff changeset
5110 while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }
a61af66fc99e Initial load
duke
parents:
diff changeset
5111
a61af66fc99e Initial load
duke
parents:
diff changeset
5112 return buf[0] == 'y' || buf[0] == 'Y';
a61af66fc99e Initial load
duke
parents:
diff changeset
5113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5114
a61af66fc99e Initial load
duke
parents:
diff changeset
5115 int os::stat(const char *path, struct stat *sbuf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5116 char pathbuf[MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
5117 if (strlen(path) > MAX_PATH - 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5118 errno = ENAMETOOLONG;
a61af66fc99e Initial load
duke
parents:
diff changeset
5119 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5120 }
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5121 os::native_path(strcpy(pathbuf, path));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5122 return ::stat(pathbuf, sbuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
5123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5124
a61af66fc99e Initial load
duke
parents:
diff changeset
5125 bool os::check_heap(bool force) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5126 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5128
a61af66fc99e Initial load
duke
parents:
diff changeset
5129 int local_vsnprintf(char* buf, size_t count, const char* format, va_list args) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5130 return ::vsnprintf(buf, count, format, args);
a61af66fc99e Initial load
duke
parents:
diff changeset
5131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5132
a61af66fc99e Initial load
duke
parents:
diff changeset
5133 // Is a (classpath) directory empty?
a61af66fc99e Initial load
duke
parents:
diff changeset
5134 bool os::dir_is_empty(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5135 DIR *dir = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5136 struct dirent *ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
5137
a61af66fc99e Initial load
duke
parents:
diff changeset
5138 dir = opendir(path);
a61af66fc99e Initial load
duke
parents:
diff changeset
5139 if (dir == NULL) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5140
a61af66fc99e Initial load
duke
parents:
diff changeset
5141 /* Scan the directory */
a61af66fc99e Initial load
duke
parents:
diff changeset
5142 bool result = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5143 char buf[sizeof(struct dirent) + MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
5144 while (result && (ptr = ::readdir(dir)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5145 if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5146 result = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5149 closedir(dir);
a61af66fc99e Initial load
duke
parents:
diff changeset
5150 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
5151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5152
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5153 // This code originates from JDK's sysOpen and open64_w
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5154 // from src/solaris/hpi/src/system_md.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5155
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5156 #ifndef O_DELETE
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5157 #define O_DELETE 0x10000
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5158 #endif
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5159
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5160 // Open a file. Unlink the file immediately after open returns
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5161 // if the specified oflag has the O_DELETE flag set.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5162 // O_DELETE is used only in j2se/src/share/native/java/util/zip/ZipFile.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5163
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5164 int os::open(const char *path, int oflag, int mode) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5165
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5166 if (strlen(path) > MAX_PATH - 1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5167 errno = ENAMETOOLONG;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5168 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5169 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5170 int fd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5171 int o_delete = (oflag & O_DELETE);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5172 oflag = oflag & ~O_DELETE;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5173
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5174 fd = ::open64(path, oflag, mode);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5175 if (fd == -1) return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5176
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5177 //If the open succeeded, the file might still be a directory
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5178 {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5179 struct stat64 buf64;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5180 int ret = ::fstat64(fd, &buf64);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5181 int st_mode = buf64.st_mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5182
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5183 if (ret != -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5184 if ((st_mode & S_IFMT) == S_IFDIR) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5185 errno = EISDIR;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5186 ::close(fd);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5187 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5188 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5189 } else {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5190 ::close(fd);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5191 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5192 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5193 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5194
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5195 /*
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5196 * All file descriptors that are opened in the JVM and not
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5197 * specifically destined for a subprocess should have the
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5198 * close-on-exec flag set. If we don't set it, then careless 3rd
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5199 * party native code might fork and exec without closing all
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5200 * appropriate file descriptors (e.g. as we do in closeDescriptors in
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5201 * UNIXProcess.c), and this in turn might:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5202 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5203 * - cause end-of-file to fail to be detected on some file
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5204 * descriptors, resulting in mysterious hangs, or
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5205 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5206 * - might cause an fopen in the subprocess to fail on a system
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5207 * suffering from bug 1085341.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5208 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5209 * (Yes, the default setting of the close-on-exec flag is a Unix
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5210 * design flaw)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5211 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5212 * See:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5213 * 1085341: 32-bit stdio routines should support file descriptors >255
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5214 * 4843136: (process) pipe file descriptor from Runtime.exec not being closed
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5215 * 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5216 */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5217 #ifdef FD_CLOEXEC
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5218 {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5219 int flags = ::fcntl(fd, F_GETFD);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5220 if (flags != -1)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5221 ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5222 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5223 #endif
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5224
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5225 if (o_delete != 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5226 ::unlink(path);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5227 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5228 return fd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5229 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5230
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5231
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5232 // create binary file, rewriting existing file if required
a61af66fc99e Initial load
duke
parents:
diff changeset
5233 int os::create_binary_file(const char* path, bool rewrite_existing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5234 int oflags = O_WRONLY | O_CREAT;
a61af66fc99e Initial load
duke
parents:
diff changeset
5235 if (!rewrite_existing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5236 oflags |= O_EXCL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5238 return ::open64(path, oflags, S_IREAD | S_IWRITE);
a61af66fc99e Initial load
duke
parents:
diff changeset
5239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5240
a61af66fc99e Initial load
duke
parents:
diff changeset
5241 // return current position of file pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
5242 jlong os::current_file_offset(int fd) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5243 return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);
a61af66fc99e Initial load
duke
parents:
diff changeset
5244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5245
a61af66fc99e Initial load
duke
parents:
diff changeset
5246 // move file pointer to the specified offset
a61af66fc99e Initial load
duke
parents:
diff changeset
5247 jlong os::seek_to_file_offset(int fd, jlong offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5248 return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);
a61af66fc99e Initial load
duke
parents:
diff changeset
5249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5250
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5251 // This code originates from JDK's sysAvailable
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5252 // from src/solaris/hpi/src/native_threads/src/sys_api_td.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5253
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5254 int os::available(int fd, jlong *bytes) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5255 jlong cur, end;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5256 int mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5257 struct stat64 buf64;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5258
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5259 if (::fstat64(fd, &buf64) >= 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5260 mode = buf64.st_mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5261 if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5262 /*
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5263 * XXX: is the following call interruptible? If so, this might
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5264 * need to go through the INTERRUPT_IO() wrapper as for other
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5265 * blocking, interruptible calls in this file.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5266 */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5267 int n;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5268 if (::ioctl(fd, FIONREAD, &n) >= 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5269 *bytes = n;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5270 return 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5271 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5272 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5273 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5274 if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5275 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5276 } else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5277 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5278 } else if (::lseek64(fd, cur, SEEK_SET) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5279 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5280 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5281 *bytes = end - cur;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5282 return 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5283 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5284
2033
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
5285 int os::socket_available(int fd, jint *pbytes) {
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
5286 // Linux doc says EINTR not returned, unlike Solaris
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
5287 int ret = ::ioctl(fd, FIONREAD, pbytes);
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
5288
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
5289 //%% note ioctl can return 0 when successful, JVM_SocketAvailable
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
5290 // is expected to return 0 on failure and 1 on success to the jdk.
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
5291 return (ret < 0) ? 0 : 1;
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
5292 }
03e1b9fce89d 7003707: need to remove (some) system include files from the HotSpot header files
dholmes
parents: 2023
diff changeset
5293
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5294 // Map a block of memory.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
5295 char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5296 char *addr, size_t bytes, bool read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
5297 bool allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5298 int prot;
5909
9eaf473fff9b 7142641: -Xshared:on fails on ARM
dlong
parents: 4854
diff changeset
5299 int flags = MAP_PRIVATE;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5300
a61af66fc99e Initial load
duke
parents:
diff changeset
5301 if (read_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5302 prot = PROT_READ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5303 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5304 prot = PROT_READ | PROT_WRITE;
a61af66fc99e Initial load
duke
parents:
diff changeset
5305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5306
a61af66fc99e Initial load
duke
parents:
diff changeset
5307 if (allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5308 prot |= PROT_EXEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
5309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5310
a61af66fc99e Initial load
duke
parents:
diff changeset
5311 if (addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5312 flags |= MAP_FIXED;
a61af66fc99e Initial load
duke
parents:
diff changeset
5313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5314
a61af66fc99e Initial load
duke
parents:
diff changeset
5315 char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
a61af66fc99e Initial load
duke
parents:
diff changeset
5316 fd, file_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
5317 if (mapped_address == MAP_FAILED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5318 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5320 return mapped_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
5321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5322
a61af66fc99e Initial load
duke
parents:
diff changeset
5323
a61af66fc99e Initial load
duke
parents:
diff changeset
5324 // Remap a block of memory.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
5325 char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5326 char *addr, size_t bytes, bool read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
5327 bool allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5328 // same as map_memory() on this OS
a61af66fc99e Initial load
duke
parents:
diff changeset
5329 return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
5330 allow_exec);
a61af66fc99e Initial load
duke
parents:
diff changeset
5331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5332
a61af66fc99e Initial load
duke
parents:
diff changeset
5333
a61af66fc99e Initial load
duke
parents:
diff changeset
5334 // Unmap a block of memory.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
5335 bool os::pd_unmap_memory(char* addr, size_t bytes) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5336 return munmap(addr, bytes) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5338
a61af66fc99e Initial load
duke
parents:
diff changeset
5339 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
5340
a61af66fc99e Initial load
duke
parents:
diff changeset
5341 static clockid_t thread_cpu_clockid(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5342 pthread_t tid = thread->osthread()->pthread_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
5343 clockid_t clockid;
a61af66fc99e Initial load
duke
parents:
diff changeset
5344
a61af66fc99e Initial load
duke
parents:
diff changeset
5345 // Get thread clockid
a61af66fc99e Initial load
duke
parents:
diff changeset
5346 int rc = os::Linux::pthread_getcpuclockid(tid, &clockid);
a61af66fc99e Initial load
duke
parents:
diff changeset
5347 assert(rc == 0, "pthread_getcpuclockid is expected to return 0 code");
a61af66fc99e Initial load
duke
parents:
diff changeset
5348 return clockid;
a61af66fc99e Initial load
duke
parents:
diff changeset
5349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5350
a61af66fc99e Initial load
duke
parents:
diff changeset
5351 // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
a61af66fc99e Initial load
duke
parents:
diff changeset
5352 // are used by JVM M&M and JVMTI to get user+sys or user CPU time
a61af66fc99e Initial load
duke
parents:
diff changeset
5353 // of a thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
5354 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5355 // current_thread_cpu_time() and thread_cpu_time(Thread*) returns
a61af66fc99e Initial load
duke
parents:
diff changeset
5356 // the fast estimate available on the platform.
a61af66fc99e Initial load
duke
parents:
diff changeset
5357
a61af66fc99e Initial load
duke
parents:
diff changeset
5358 jlong os::current_thread_cpu_time() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5359 if (os::Linux::supports_fast_thread_cpu_time()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5360 return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
5361 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5362 // return user + sys since the cost is the same
a61af66fc99e Initial load
duke
parents:
diff changeset
5363 return slow_thread_cpu_time(Thread::current(), true /* user + sys */);
a61af66fc99e Initial load
duke
parents:
diff changeset
5364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5366
a61af66fc99e Initial load
duke
parents:
diff changeset
5367 jlong os::thread_cpu_time(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5368 // consistent with what current_thread_cpu_time() returns
a61af66fc99e Initial load
duke
parents:
diff changeset
5369 if (os::Linux::supports_fast_thread_cpu_time()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5370 return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
a61af66fc99e Initial load
duke
parents:
diff changeset
5371 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5372 return slow_thread_cpu_time(thread, true /* user + sys */);
a61af66fc99e Initial load
duke
parents:
diff changeset
5373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5375
a61af66fc99e Initial load
duke
parents:
diff changeset
5376 jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5377 if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5378 return os::Linux::fast_thread_cpu_time(CLOCK_THREAD_CPUTIME_ID);
a61af66fc99e Initial load
duke
parents:
diff changeset
5379 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5380 return slow_thread_cpu_time(Thread::current(), user_sys_cpu_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
5381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5383
a61af66fc99e Initial load
duke
parents:
diff changeset
5384 jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5385 if (user_sys_cpu_time && os::Linux::supports_fast_thread_cpu_time()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5386 return os::Linux::fast_thread_cpu_time(thread_cpu_clockid(thread));
a61af66fc99e Initial load
duke
parents:
diff changeset
5387 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5388 return slow_thread_cpu_time(thread, user_sys_cpu_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
5389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5390 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5391
a61af66fc99e Initial load
duke
parents:
diff changeset
5392 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5393 // -1 on error.
a61af66fc99e Initial load
duke
parents:
diff changeset
5394 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5395
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
5396 PRAGMA_DIAG_PUSH
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
5397 PRAGMA_FORMAT_NONLITERAL_IGNORED
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5398 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5399 static bool proc_task_unchecked = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5400 static const char *proc_stat_path = "/proc/%d/stat";
a61af66fc99e Initial load
duke
parents:
diff changeset
5401 pid_t tid = thread->osthread()->thread_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
5402 char *s;
a61af66fc99e Initial load
duke
parents:
diff changeset
5403 char stat[2048];
a61af66fc99e Initial load
duke
parents:
diff changeset
5404 int statlen;
a61af66fc99e Initial load
duke
parents:
diff changeset
5405 char proc_name[64];
a61af66fc99e Initial load
duke
parents:
diff changeset
5406 int count;
a61af66fc99e Initial load
duke
parents:
diff changeset
5407 long sys_time, user_time;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5408 char cdummy;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5409 int idummy;
a61af66fc99e Initial load
duke
parents:
diff changeset
5410 long ldummy;
a61af66fc99e Initial load
duke
parents:
diff changeset
5411 FILE *fp;
a61af66fc99e Initial load
duke
parents:
diff changeset
5412
a61af66fc99e Initial load
duke
parents:
diff changeset
5413 // The /proc/<tid>/stat aggregates per-process usage on
a61af66fc99e Initial load
duke
parents:
diff changeset
5414 // new Linux kernels 2.6+ where NPTL is supported.
a61af66fc99e Initial load
duke
parents:
diff changeset
5415 // The /proc/self/task/<tid>/stat still has the per-thread usage.
a61af66fc99e Initial load
duke
parents:
diff changeset
5416 // See bug 6328462.
8099
4c1d8002ffb1 8004495: [parfait] False positive Buffer overflow in hotspot/src/os/linux/vm/os_linux.cpp
hseigel
parents: 8067
diff changeset
5417 // There possibly can be cases where there is no directory
4c1d8002ffb1 8004495: [parfait] False positive Buffer overflow in hotspot/src/os/linux/vm/os_linux.cpp
hseigel
parents: 8067
diff changeset
5418 // /proc/self/task, so we check its availability.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5419 if (proc_task_unchecked && os::Linux::is_NPTL()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5420 // This is executed only once
a61af66fc99e Initial load
duke
parents:
diff changeset
5421 proc_task_unchecked = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5422 fp = fopen("/proc/self/task", "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
5423 if (fp != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5424 proc_stat_path = "/proc/self/task/%d/stat";
a61af66fc99e Initial load
duke
parents:
diff changeset
5425 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
5426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5428
a61af66fc99e Initial load
duke
parents:
diff changeset
5429 sprintf(proc_name, proc_stat_path, tid);
a61af66fc99e Initial load
duke
parents:
diff changeset
5430 fp = fopen(proc_name, "r");
a61af66fc99e Initial load
duke
parents:
diff changeset
5431 if ( fp == NULL ) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5432 statlen = fread(stat, 1, 2047, fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
5433 stat[statlen] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
5434 fclose(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
5435
a61af66fc99e Initial load
duke
parents:
diff changeset
5436 // Skip pid and the command string. Note that we could be dealing with
a61af66fc99e Initial load
duke
parents:
diff changeset
5437 // weird command names, e.g. user could decide to rename java launcher
a61af66fc99e Initial load
duke
parents:
diff changeset
5438 // to "java 1.4.2 :)", then the stat file would look like
a61af66fc99e Initial load
duke
parents:
diff changeset
5439 // 1234 (java 1.4.2 :)) R ... ...
a61af66fc99e Initial load
duke
parents:
diff changeset
5440 // We don't really need to know the command string, just find the last
a61af66fc99e Initial load
duke
parents:
diff changeset
5441 // occurrence of ")" and then start parsing from there. See bug 4726580.
a61af66fc99e Initial load
duke
parents:
diff changeset
5442 s = strrchr(stat, ')');
a61af66fc99e Initial load
duke
parents:
diff changeset
5443 if (s == NULL ) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5444
a61af66fc99e Initial load
duke
parents:
diff changeset
5445 // Skip blank chars
a61af66fc99e Initial load
duke
parents:
diff changeset
5446 do s++; while (isspace(*s));
a61af66fc99e Initial load
duke
parents:
diff changeset
5447
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5448 count = sscanf(s,"%c %d %d %d %d %d %lu %lu %lu %lu %lu %lu %lu",
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5449 &cdummy, &idummy, &idummy, &idummy, &idummy, &idummy,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5450 &ldummy, &ldummy, &ldummy, &ldummy, &ldummy,
a61af66fc99e Initial load
duke
parents:
diff changeset
5451 &user_time, &sys_time);
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5452 if ( count != 13 ) return -1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5453 if (user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5454 return ((jlong)sys_time + (jlong)user_time) * (1000000000 / clock_tics_per_sec);
a61af66fc99e Initial load
duke
parents:
diff changeset
5455 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5456 return (jlong)user_time * (1000000000 / clock_tics_per_sec);
a61af66fc99e Initial load
duke
parents:
diff changeset
5457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5458 }
17937
78bbf4d43a14 8037816: Fix for 8036122 breaks build with Xcode5/clang
drchase
parents: 17848
diff changeset
5459 PRAGMA_DIAG_POP
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5460
a61af66fc99e Initial load
duke
parents:
diff changeset
5461 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5462 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
5463 info_ptr->may_skip_backward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5464 info_ptr->may_skip_forward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5465 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned
a61af66fc99e Initial load
duke
parents:
diff changeset
5466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5467
a61af66fc99e Initial load
duke
parents:
diff changeset
5468 void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5469 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
5470 info_ptr->may_skip_backward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5471 info_ptr->may_skip_forward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5472 info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned
a61af66fc99e Initial load
duke
parents:
diff changeset
5473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5474
a61af66fc99e Initial load
duke
parents:
diff changeset
5475 bool os::is_thread_cpu_time_supported() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5476 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5478
a61af66fc99e Initial load
duke
parents:
diff changeset
5479 // System loadavg support. Returns -1 if load average cannot be obtained.
a61af66fc99e Initial load
duke
parents:
diff changeset
5480 // Linux doesn't yet have a (official) notion of processor sets,
a61af66fc99e Initial load
duke
parents:
diff changeset
5481 // so just return the system wide load average.
a61af66fc99e Initial load
duke
parents:
diff changeset
5482 int os::loadavg(double loadavg[], int nelem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5483 return ::getloadavg(loadavg, nelem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5484 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5485
a61af66fc99e Initial load
duke
parents:
diff changeset
5486 void os::pause() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5487 char filename[MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
5488 if (PauseAtStartupFile && PauseAtStartupFile[0]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5489 jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
a61af66fc99e Initial load
duke
parents:
diff changeset
5490 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5491 jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
5492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5493
a61af66fc99e Initial load
duke
parents:
diff changeset
5494 int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
a61af66fc99e Initial load
duke
parents:
diff changeset
5495 if (fd != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5496 struct stat buf;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5497 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5498 while (::stat(filename, &buf) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5499 (void)::poll(NULL, 0, 100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5501 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5502 jio_fprintf(stderr,
a61af66fc99e Initial load
duke
parents:
diff changeset
5503 "Could not open pause file '%s', continuing immediately.\n", filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
5504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5506
a61af66fc99e Initial load
duke
parents:
diff changeset
5507
a61af66fc99e Initial load
duke
parents:
diff changeset
5508 // Refer to the comments in os_solaris.cpp park-unpark.
a61af66fc99e Initial load
duke
parents:
diff changeset
5509 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5510 // Beware -- Some versions of NPTL embody a flaw where pthread_cond_timedwait() can
a61af66fc99e Initial load
duke
parents:
diff changeset
5511 // hang indefinitely. For instance NPTL 0.60 on 2.4.21-4ELsmp is vulnerable.
a61af66fc99e Initial load
duke
parents:
diff changeset
5512 // For specifics regarding the bug see GLIBC BUGID 261237 :
a61af66fc99e Initial load
duke
parents:
diff changeset
5513 // http://www.mail-archive.com/debian-glibc@lists.debian.org/msg10837.html.
a61af66fc99e Initial load
duke
parents:
diff changeset
5514 // Briefly, pthread_cond_timedwait() calls with an expiry time that's not in the future
a61af66fc99e Initial load
duke
parents:
diff changeset
5515 // will either hang or corrupt the condvar, resulting in subsequent hangs if the condvar
a61af66fc99e Initial load
duke
parents:
diff changeset
5516 // is used. (The simple C test-case provided in the GLIBC bug report manifests the
a61af66fc99e Initial load
duke
parents:
diff changeset
5517 // hang). The JVM is vulernable via sleep(), Object.wait(timo), LockSupport.parkNanos()
a61af66fc99e Initial load
duke
parents:
diff changeset
5518 // and monitorenter when we're using 1-0 locking. All those operations may result in
a61af66fc99e Initial load
duke
parents:
diff changeset
5519 // calls to pthread_cond_timedwait(). Using LD_ASSUME_KERNEL to use an older version
a61af66fc99e Initial load
duke
parents:
diff changeset
5520 // of libpthread avoids the problem, but isn't practical.
a61af66fc99e Initial load
duke
parents:
diff changeset
5521 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5522 // Possible remedies:
a61af66fc99e Initial load
duke
parents:
diff changeset
5523 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5524 // 1. Establish a minimum relative wait time. 50 to 100 msecs seems to work.
a61af66fc99e Initial load
duke
parents:
diff changeset
5525 // This is palliative and probabilistic, however. If the thread is preempted
a61af66fc99e Initial load
duke
parents:
diff changeset
5526 // between the call to compute_abstime() and pthread_cond_timedwait(), more
a61af66fc99e Initial load
duke
parents:
diff changeset
5527 // than the minimum period may have passed, and the abstime may be stale (in the
a61af66fc99e Initial load
duke
parents:
diff changeset
5528 // past) resultin in a hang. Using this technique reduces the odds of a hang
a61af66fc99e Initial load
duke
parents:
diff changeset
5529 // but the JVM is still vulnerable, particularly on heavily loaded systems.
a61af66fc99e Initial load
duke
parents:
diff changeset
5530 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5531 // 2. Modify park-unpark to use per-thread (per ParkEvent) pipe-pairs instead
a61af66fc99e Initial load
duke
parents:
diff changeset
5532 // of the usual flag-condvar-mutex idiom. The write side of the pipe is set
a61af66fc99e Initial load
duke
parents:
diff changeset
5533 // NDELAY. unpark() reduces to write(), park() reduces to read() and park(timo)
a61af66fc99e Initial load
duke
parents:
diff changeset
5534 // reduces to poll()+read(). This works well, but consumes 2 FDs per extant
a61af66fc99e Initial load
duke
parents:
diff changeset
5535 // thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
5536 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5537 // 3. Embargo pthread_cond_timedwait() and implement a native "chron" thread
a61af66fc99e Initial load
duke
parents:
diff changeset
5538 // that manages timeouts. We'd emulate pthread_cond_timedwait() by enqueuing
a61af66fc99e Initial load
duke
parents:
diff changeset
5539 // a timeout request to the chron thread and then blocking via pthread_cond_wait().
a61af66fc99e Initial load
duke
parents:
diff changeset
5540 // This also works well. In fact it avoids kernel-level scalability impediments
a61af66fc99e Initial load
duke
parents:
diff changeset
5541 // on certain platforms that don't handle lots of active pthread_cond_timedwait()
a61af66fc99e Initial load
duke
parents:
diff changeset
5542 // timers in a graceful fashion.
a61af66fc99e Initial load
duke
parents:
diff changeset
5543 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5544 // 4. When the abstime value is in the past it appears that control returns
a61af66fc99e Initial load
duke
parents:
diff changeset
5545 // correctly from pthread_cond_timedwait(), but the condvar is left corrupt.
a61af66fc99e Initial load
duke
parents:
diff changeset
5546 // Subsequent timedwait/wait calls may hang indefinitely. Given that, we
a61af66fc99e Initial load
duke
parents:
diff changeset
5547 // can avoid the problem by reinitializing the condvar -- by cond_destroy()
a61af66fc99e Initial load
duke
parents:
diff changeset
5548 // followed by cond_init() -- after all calls to pthread_cond_timedwait().
a61af66fc99e Initial load
duke
parents:
diff changeset
5549 // It may be possible to avoid reinitialization by checking the return
a61af66fc99e Initial load
duke
parents:
diff changeset
5550 // value from pthread_cond_timedwait(). In addition to reinitializing the
a61af66fc99e Initial load
duke
parents:
diff changeset
5551 // condvar we must establish the invariant that cond_signal() is only called
a61af66fc99e Initial load
duke
parents:
diff changeset
5552 // within critical sections protected by the adjunct mutex. This prevents
a61af66fc99e Initial load
duke
parents:
diff changeset
5553 // cond_signal() from "seeing" a condvar that's in the midst of being
a61af66fc99e Initial load
duke
parents:
diff changeset
5554 // reinitialized or that is corrupt. Sadly, this invariant obviates the
a61af66fc99e Initial load
duke
parents:
diff changeset
5555 // desirable signal-after-unlock optimization that avoids futile context switching.
a61af66fc99e Initial load
duke
parents:
diff changeset
5556 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5557 // I'm also concerned that some versions of NTPL might allocate an auxilliary
a61af66fc99e Initial load
duke
parents:
diff changeset
5558 // structure when a condvar is used or initialized. cond_destroy() would
a61af66fc99e Initial load
duke
parents:
diff changeset
5559 // release the helper structure. Our reinitialize-after-timedwait fix
a61af66fc99e Initial load
duke
parents:
diff changeset
5560 // put excessive stress on malloc/free and locks protecting the c-heap.
a61af66fc99e Initial load
duke
parents:
diff changeset
5561 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5562 // We currently use (4). See the WorkAroundNTPLTimedWaitHang flag.
a61af66fc99e Initial load
duke
parents:
diff changeset
5563 // It may be possible to refine (4) by checking the kernel and NTPL verisons
a61af66fc99e Initial load
duke
parents:
diff changeset
5564 // and only enabling the work-around for vulnerable environments.
a61af66fc99e Initial load
duke
parents:
diff changeset
5565
a61af66fc99e Initial load
duke
parents:
diff changeset
5566 // utility to compute the abstime argument to timedwait:
a61af66fc99e Initial load
duke
parents:
diff changeset
5567 // millis is the relative timeout time
a61af66fc99e Initial load
duke
parents:
diff changeset
5568 // abstime will be the absolute timeout time
a61af66fc99e Initial load
duke
parents:
diff changeset
5569 // TODO: replace compute_abstime() with unpackTime()
a61af66fc99e Initial load
duke
parents:
diff changeset
5570
a61af66fc99e Initial load
duke
parents:
diff changeset
5571 static struct timespec* compute_abstime(timespec* abstime, jlong millis) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5572 if (millis < 0) millis = 0;
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5573
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5574 jlong seconds = millis / 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5575 millis %= 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5576 if (seconds > 50000000) { // see man cond_timedwait(3T)
a61af66fc99e Initial load
duke
parents:
diff changeset
5577 seconds = 50000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
5578 }
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5579
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5580 if (os::Linux::supports_monotonic_clock()) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5581 struct timespec now;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5582 int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now);
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5583 assert_status(status == 0, status, "clock_gettime");
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5584 abstime->tv_sec = now.tv_sec + seconds;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5585 long nanos = now.tv_nsec + millis * NANOSECS_PER_MILLISEC;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5586 if (nanos >= NANOSECS_PER_SEC) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5587 abstime->tv_sec += 1;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5588 nanos -= NANOSECS_PER_SEC;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5589 }
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5590 abstime->tv_nsec = nanos;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5591 } else {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5592 struct timeval now;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5593 int status = gettimeofday(&now, NULL);
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5594 assert(status == 0, "gettimeofday");
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5595 abstime->tv_sec = now.tv_sec + seconds;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5596 long usec = now.tv_usec + millis * 1000;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5597 if (usec >= 1000000) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5598 abstime->tv_sec += 1;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5599 usec -= 1000000;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5600 }
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5601 abstime->tv_nsec = usec * 1000;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5602 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5603 return abstime;
a61af66fc99e Initial load
duke
parents:
diff changeset
5604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5605
a61af66fc99e Initial load
duke
parents:
diff changeset
5606
a61af66fc99e Initial load
duke
parents:
diff changeset
5607 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
5608 // Conceptually TryPark() should be equivalent to park(0).
a61af66fc99e Initial load
duke
parents:
diff changeset
5609
a61af66fc99e Initial load
duke
parents:
diff changeset
5610 int os::PlatformEvent::TryPark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5611 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5612 const int v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5613 guarantee ((v == 0) || (v == 1), "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5614 if (Atomic::cmpxchg (0, &_Event, v) == v) return v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5617
a61af66fc99e Initial load
duke
parents:
diff changeset
5618 void os::PlatformEvent::park() { // AKA "down()"
a61af66fc99e Initial load
duke
parents:
diff changeset
5619 // Invariant: Only the thread associated with the Event/PlatformEvent
a61af66fc99e Initial load
duke
parents:
diff changeset
5620 // may call park().
a61af66fc99e Initial load
duke
parents:
diff changeset
5621 // TODO: assert that _Assoc != NULL or _Assoc == Self
a61af66fc99e Initial load
duke
parents:
diff changeset
5622 int v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5623 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5624 v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5625 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5627 guarantee (v >= 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5628 if (v == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5629 // Do this the hard way by blocking ...
a61af66fc99e Initial load
duke
parents:
diff changeset
5630 int status = pthread_mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5631 assert_status(status == 0, status, "mutex_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
5632 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5633 ++ _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5634 while (_Event < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5635 status = pthread_cond_wait(_cond, _mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5636 // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
a61af66fc99e Initial load
duke
parents:
diff changeset
5637 // Treat this the same as if the wait was interrupted
a61af66fc99e Initial load
duke
parents:
diff changeset
5638 if (status == ETIME) { status = EINTR; }
a61af66fc99e Initial load
duke
parents:
diff changeset
5639 assert_status(status == 0 || status == EINTR, status, "cond_wait");
a61af66fc99e Initial load
duke
parents:
diff changeset
5640 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5641 -- _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5642
a61af66fc99e Initial load
duke
parents:
diff changeset
5643 _Event = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5644 status = pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5645 assert_status(status == 0, status, "mutex_unlock");
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5646 // Paranoia to ensure our locked and lock-free paths interact
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5647 // correctly with each other.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5648 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5650 guarantee (_Event >= 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5651 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5652
a61af66fc99e Initial load
duke
parents:
diff changeset
5653 int os::PlatformEvent::park(jlong millis) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5654 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5655
a61af66fc99e Initial load
duke
parents:
diff changeset
5656 int v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5657 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5658 v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5659 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5661 guarantee (v >= 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5662 if (v != 0) return OS_OK ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5663
a61af66fc99e Initial load
duke
parents:
diff changeset
5664 // We do this the hard way, by blocking the thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
5665 // Consider enforcing a minimum timeout value.
a61af66fc99e Initial load
duke
parents:
diff changeset
5666 struct timespec abst;
a61af66fc99e Initial load
duke
parents:
diff changeset
5667 compute_abstime(&abst, millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
5668
a61af66fc99e Initial load
duke
parents:
diff changeset
5669 int ret = OS_TIMEOUT;
a61af66fc99e Initial load
duke
parents:
diff changeset
5670 int status = pthread_mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5671 assert_status(status == 0, status, "mutex_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
5672 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5673 ++_nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5674
a61af66fc99e Initial load
duke
parents:
diff changeset
5675 // Object.wait(timo) will return because of
a61af66fc99e Initial load
duke
parents:
diff changeset
5676 // (a) notification
a61af66fc99e Initial load
duke
parents:
diff changeset
5677 // (b) timeout
a61af66fc99e Initial load
duke
parents:
diff changeset
5678 // (c) thread.interrupt
a61af66fc99e Initial load
duke
parents:
diff changeset
5679 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5680 // Thread.interrupt and object.notify{All} both call Event::set.
a61af66fc99e Initial load
duke
parents:
diff changeset
5681 // That is, we treat thread.interrupt as a special case of notification.
a61af66fc99e Initial load
duke
parents:
diff changeset
5682 // The underlying Solaris implementation, cond_timedwait, admits
a61af66fc99e Initial load
duke
parents:
diff changeset
5683 // spurious/premature wakeups, but the JLS/JVM spec prevents the
a61af66fc99e Initial load
duke
parents:
diff changeset
5684 // JVM from making those visible to Java code. As such, we must
a61af66fc99e Initial load
duke
parents:
diff changeset
5685 // filter out spurious wakeups. We assume all ETIME returns are valid.
a61af66fc99e Initial load
duke
parents:
diff changeset
5686 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5687 // TODO: properly differentiate simultaneous notify+interrupt.
a61af66fc99e Initial load
duke
parents:
diff changeset
5688 // In that case, we should propagate the notify to another waiter.
a61af66fc99e Initial load
duke
parents:
diff changeset
5689
a61af66fc99e Initial load
duke
parents:
diff changeset
5690 while (_Event < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5691 status = os::Linux::safe_cond_timedwait(_cond, _mutex, &abst);
a61af66fc99e Initial load
duke
parents:
diff changeset
5692 if (status != 0 && WorkAroundNPTLTimedWaitHang) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5693 pthread_cond_destroy (_cond);
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5694 pthread_cond_init (_cond, os::Linux::condAttr()) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5696 assert_status(status == 0 || status == EINTR ||
a61af66fc99e Initial load
duke
parents:
diff changeset
5697 status == ETIME || status == ETIMEDOUT,
a61af66fc99e Initial load
duke
parents:
diff changeset
5698 status, "cond_timedwait");
a61af66fc99e Initial load
duke
parents:
diff changeset
5699 if (!FilterSpuriousWakeups) break ; // previous semantics
a61af66fc99e Initial load
duke
parents:
diff changeset
5700 if (status == ETIME || status == ETIMEDOUT) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5701 // We consume and ignore EINTR and spurious wakeups.
a61af66fc99e Initial load
duke
parents:
diff changeset
5702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5703 --_nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5704 if (_Event >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5705 ret = OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
5706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5707 _Event = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5708 status = pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5709 assert_status(status == 0, status, "mutex_unlock");
a61af66fc99e Initial load
duke
parents:
diff changeset
5710 assert (_nParked == 0, "invariant") ;
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5711 // Paranoia to ensure our locked and lock-free paths interact
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5712 // correctly with each other.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5713 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5714 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
5715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5716
a61af66fc99e Initial load
duke
parents:
diff changeset
5717 void os::PlatformEvent::unpark() {
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5718 // Transitions for _Event:
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5719 // 0 :=> 1
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5720 // 1 :=> 1
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5721 // -1 :=> either 0 or 1; must signal target thread
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5722 // That is, we can safely transition _Event from -1 to either
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5723 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5724 // unpark() calls.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5725 // See also: "Semaphores in Plan 9" by Mullender & Cox
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5726 //
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5727 // Note: Forcing a transition from "-1" to "1" on an unpark() means
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5728 // that it will take two back-to-back park() calls for the owning
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5729 // thread to block. This has the benefit of forcing a spurious return
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5730 // from the first park() call after an unpark() call which will help
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5731 // shake out uses of park() and unpark() without condition variables.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5732
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5733 if (Atomic::xchg(1, &_Event) >= 0) return;
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5734
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5735 // Wait for the thread associated with the event to vacate
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5736 int status = pthread_mutex_lock(_mutex);
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5737 assert_status(status == 0, status, "mutex_lock");
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5738 int AnyWaiters = _nParked;
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5739 assert(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5740 if (AnyWaiters != 0 && WorkAroundNPTLTimedWaitHang) {
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5741 AnyWaiters = 0;
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5742 pthread_cond_signal(_cond);
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5743 }
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5744 status = pthread_mutex_unlock(_mutex);
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5745 assert_status(status == 0, status, "mutex_unlock");
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5746 if (AnyWaiters != 0) {
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5747 status = pthread_cond_signal(_cond);
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5748 assert_status(status == 0, status, "cond_signal");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5750
a61af66fc99e Initial load
duke
parents:
diff changeset
5751 // Note that we signal() _after dropping the lock for "immortal" Events.
a61af66fc99e Initial load
duke
parents:
diff changeset
5752 // This is safe and avoids a common class of futile wakeups. In rare
a61af66fc99e Initial load
duke
parents:
diff changeset
5753 // circumstances this can cause a thread to return prematurely from
a61af66fc99e Initial load
duke
parents:
diff changeset
5754 // cond_{timed}wait() but the spurious wakeup is benign and the victim will
a61af66fc99e Initial load
duke
parents:
diff changeset
5755 // simply re-test the condition and re-park itself.
a61af66fc99e Initial load
duke
parents:
diff changeset
5756 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5757
a61af66fc99e Initial load
duke
parents:
diff changeset
5758
a61af66fc99e Initial load
duke
parents:
diff changeset
5759 // JSR166
a61af66fc99e Initial load
duke
parents:
diff changeset
5760 // -------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5761
a61af66fc99e Initial load
duke
parents:
diff changeset
5762 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
5763 * The solaris and linux implementations of park/unpark are fairly
a61af66fc99e Initial load
duke
parents:
diff changeset
5764 * conservative for now, but can be improved. They currently use a
a61af66fc99e Initial load
duke
parents:
diff changeset
5765 * mutex/condvar pair, plus a a count.
a61af66fc99e Initial load
duke
parents:
diff changeset
5766 * Park decrements count if > 0, else does a condvar wait. Unpark
a61af66fc99e Initial load
duke
parents:
diff changeset
5767 * sets count to 1 and signals condvar. Only one thread ever waits
a61af66fc99e Initial load
duke
parents:
diff changeset
5768 * on the condvar. Contention seen when trying to park implies that someone
a61af66fc99e Initial load
duke
parents:
diff changeset
5769 * is unparking you, so don't wait. And spurious returns are fine, so there
a61af66fc99e Initial load
duke
parents:
diff changeset
5770 * is no need to track notifications.
a61af66fc99e Initial load
duke
parents:
diff changeset
5771 */
a61af66fc99e Initial load
duke
parents:
diff changeset
5772
a61af66fc99e Initial load
duke
parents:
diff changeset
5773 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
5774 * This code is common to linux and solaris and will be moved to a
a61af66fc99e Initial load
duke
parents:
diff changeset
5775 * common place in dolphin.
a61af66fc99e Initial load
duke
parents:
diff changeset
5776 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5777 * The passed in time value is either a relative time in nanoseconds
a61af66fc99e Initial load
duke
parents:
diff changeset
5778 * or an absolute time in milliseconds. Either way it has to be unpacked
a61af66fc99e Initial load
duke
parents:
diff changeset
5779 * into suitable seconds and nanoseconds components and stored in the
a61af66fc99e Initial load
duke
parents:
diff changeset
5780 * given timespec structure.
a61af66fc99e Initial load
duke
parents:
diff changeset
5781 * Given time is a 64-bit value and the time_t used in the timespec is only
a61af66fc99e Initial load
duke
parents:
diff changeset
5782 * a signed-32-bit value (except on 64-bit Linux) we have to watch for
a61af66fc99e Initial load
duke
parents:
diff changeset
5783 * overflow if times way in the future are given. Further on Solaris versions
a61af66fc99e Initial load
duke
parents:
diff changeset
5784 * prior to 10 there is a restriction (see cond_timedwait) that the specified
a61af66fc99e Initial load
duke
parents:
diff changeset
5785 * number of seconds, in abstime, is less than current_time + 100,000,000.
a61af66fc99e Initial load
duke
parents:
diff changeset
5786 * As it will be 28 years before "now + 100000000" will overflow we can
a61af66fc99e Initial load
duke
parents:
diff changeset
5787 * ignore overflow and just impose a hard-limit on seconds using the value
a61af66fc99e Initial load
duke
parents:
diff changeset
5788 * of "now + 100,000,000". This places a limit on the timeout of about 3.17
a61af66fc99e Initial load
duke
parents:
diff changeset
5789 * years from "now".
a61af66fc99e Initial load
duke
parents:
diff changeset
5790 */
a61af66fc99e Initial load
duke
parents:
diff changeset
5791
a61af66fc99e Initial load
duke
parents:
diff changeset
5792 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5793 assert (time > 0, "convertTime");
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5794 time_t max_secs = 0;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5795
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5796 if (!os::Linux::supports_monotonic_clock() || isAbsolute) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5797 struct timeval now;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5798 int status = gettimeofday(&now, NULL);
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5799 assert(status == 0, "gettimeofday");
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5800
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5801 max_secs = now.tv_sec + MAX_SECS;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5802
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5803 if (isAbsolute) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5804 jlong secs = time / 1000;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5805 if (secs > max_secs) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5806 absTime->tv_sec = max_secs;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5807 } else {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5808 absTime->tv_sec = secs;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5809 }
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5810 absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5811 } else {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5812 jlong secs = time / NANOSECS_PER_SEC;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5813 if (secs >= MAX_SECS) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5814 absTime->tv_sec = max_secs;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5815 absTime->tv_nsec = 0;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5816 } else {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5817 absTime->tv_sec = now.tv_sec + secs;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5818 absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5819 if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5820 absTime->tv_nsec -= NANOSECS_PER_SEC;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5821 ++absTime->tv_sec; // note: this must be <= max_secs
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5822 }
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5823 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5824 }
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5825 } else {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5826 // must be relative using monotonic clock
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5827 struct timespec now;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5828 int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now);
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5829 assert_status(status == 0, status, "clock_gettime");
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5830 max_secs = now.tv_sec + MAX_SECS;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5831 jlong secs = time / NANOSECS_PER_SEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
5832 if (secs >= MAX_SECS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5833 absTime->tv_sec = max_secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
5834 absTime->tv_nsec = 0;
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5835 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5836 absTime->tv_sec = now.tv_sec + secs;
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5837 absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_nsec;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5838 if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5839 absTime->tv_nsec -= NANOSECS_PER_SEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
5840 ++absTime->tv_sec; // note: this must be <= max_secs
a61af66fc99e Initial load
duke
parents:
diff changeset
5841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5844 assert(absTime->tv_sec >= 0, "tv_sec < 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
5845 assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
a61af66fc99e Initial load
duke
parents:
diff changeset
5846 assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
5847 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
a61af66fc99e Initial load
duke
parents:
diff changeset
5848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5849
a61af66fc99e Initial load
duke
parents:
diff changeset
5850 void Parker::park(bool isAbsolute, jlong time) {
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5851 // Ideally we'd do something useful while spinning, such
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5852 // as calling unpackTime().
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5853
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5854 // Optional fast-path check:
a61af66fc99e Initial load
duke
parents:
diff changeset
5855 // Return immediately if a permit is available.
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5856 // We depend on Atomic::xchg() having full barrier semantics
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5857 // since we are doing a lock-free update to _counter.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5858 if (Atomic::xchg(0, &_counter) > 0) return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5859
a61af66fc99e Initial load
duke
parents:
diff changeset
5860 Thread* thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
5861 assert(thread->is_Java_thread(), "Must be JavaThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
5862 JavaThread *jt = (JavaThread *)thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
5863
a61af66fc99e Initial load
duke
parents:
diff changeset
5864 // Optional optimization -- avoid state transitions if there's an interrupt pending.
a61af66fc99e Initial load
duke
parents:
diff changeset
5865 // Check interrupt before trying to wait
a61af66fc99e Initial load
duke
parents:
diff changeset
5866 if (Thread::is_interrupted(thread, false)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5867 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
5868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5869
a61af66fc99e Initial load
duke
parents:
diff changeset
5870 // Next, demultiplex/decode time arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
5871 timespec absTime;
1865
1c352af0135d 6763959: java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
acorn
parents: 1750
diff changeset
5872 if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5873 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
5874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5875 if (time > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5876 unpackTime(&absTime, isAbsolute, time);
a61af66fc99e Initial load
duke
parents:
diff changeset
5877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5878
a61af66fc99e Initial load
duke
parents:
diff changeset
5879
a61af66fc99e Initial load
duke
parents:
diff changeset
5880 // Enter safepoint region
a61af66fc99e Initial load
duke
parents:
diff changeset
5881 // Beware of deadlocks such as 6317397.
a61af66fc99e Initial load
duke
parents:
diff changeset
5882 // The per-thread Parker:: mutex is a classic leaf-lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
5883 // In particular a thread must never block on the Threads_lock while
a61af66fc99e Initial load
duke
parents:
diff changeset
5884 // holding the Parker:: mutex. If safepoints are pending both the
a61af66fc99e Initial load
duke
parents:
diff changeset
5885 // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
5886 ThreadBlockInVM tbivm(jt);
a61af66fc99e Initial load
duke
parents:
diff changeset
5887
a61af66fc99e Initial load
duke
parents:
diff changeset
5888 // Don't wait if cannot get lock since interference arises from
a61af66fc99e Initial load
duke
parents:
diff changeset
5889 // unblocking. Also. check interrupt before trying wait
a61af66fc99e Initial load
duke
parents:
diff changeset
5890 if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5891 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
5892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5893
a61af66fc99e Initial load
duke
parents:
diff changeset
5894 int status ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5895 if (_counter > 0) { // no wait needed
a61af66fc99e Initial load
duke
parents:
diff changeset
5896 _counter = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5897 status = pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5898 assert (status == 0, "invariant") ;
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5899 // Paranoia to ensure our locked and lock-free paths interact
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5900 // correctly with each other and Java-level accesses.
1117
95e9083cf4a7 6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents: 1010
diff changeset
5901 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5902 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
5903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5904
a61af66fc99e Initial load
duke
parents:
diff changeset
5905 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
5906 // Don't catch signals while blocked; let the running threads have the signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
5907 // (This allows a debugger to break into the running thread.)
a61af66fc99e Initial load
duke
parents:
diff changeset
5908 sigset_t oldsigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
5909 sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals();
a61af66fc99e Initial load
duke
parents:
diff changeset
5910 pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
5911 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5912
a61af66fc99e Initial load
duke
parents:
diff changeset
5913 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
5914 jt->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
5915 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
a61af66fc99e Initial load
duke
parents:
diff changeset
5916
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5917 assert(_cur_index == -1, "invariant");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5918 if (time == 0) {
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5919 _cur_index = REL_INDEX; // arbitrary choice when not timed
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5920 status = pthread_cond_wait (&_cond[_cur_index], _mutex) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5921 } else {
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5922 _cur_index = isAbsolute ? ABS_INDEX : REL_INDEX;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5923 status = os::Linux::safe_cond_timedwait (&_cond[_cur_index], _mutex, &absTime) ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5924 if (status != 0 && WorkAroundNPTLTimedWaitHang) {
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5925 pthread_cond_destroy (&_cond[_cur_index]) ;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5926 pthread_cond_init (&_cond[_cur_index], isAbsolute ? NULL : os::Linux::condAttr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5928 }
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5929 _cur_index = -1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5930 assert_status(status == 0 || status == EINTR ||
a61af66fc99e Initial load
duke
parents:
diff changeset
5931 status == ETIME || status == ETIMEDOUT,
a61af66fc99e Initial load
duke
parents:
diff changeset
5932 status, "cond_timedwait");
a61af66fc99e Initial load
duke
parents:
diff changeset
5933
a61af66fc99e Initial load
duke
parents:
diff changeset
5934 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
5935 pthread_sigmask(SIG_SETMASK, &oldsigs, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
5936 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5937
a61af66fc99e Initial load
duke
parents:
diff changeset
5938 _counter = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5939 status = pthread_mutex_unlock(_mutex) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5940 assert_status(status == 0, status, "invariant") ;
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5941 // Paranoia to ensure our locked and lock-free paths interact
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5942 // correctly with each other and Java-level accesses.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5943 OrderAccess::fence();
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
5944
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5945 // If externally suspended while waiting, re-suspend
a61af66fc99e Initial load
duke
parents:
diff changeset
5946 if (jt->handle_special_suspend_equivalent_condition()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5947 jt->java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
5948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5950
a61af66fc99e Initial load
duke
parents:
diff changeset
5951 void Parker::unpark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5952 int s, status ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5953 status = pthread_mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5954 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5955 s = _counter;
a61af66fc99e Initial load
duke
parents:
diff changeset
5956 _counter = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5957 if (s < 1) {
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5958 // thread might be parked
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5959 if (_cur_index != -1) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5960 // thread is definitely parked
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5961 if (WorkAroundNPTLTimedWaitHang) {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5962 status = pthread_cond_signal (&_cond[_cur_index]);
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5963 assert (status == 0, "invariant");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5964 status = pthread_mutex_unlock(_mutex);
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5965 assert (status == 0, "invariant");
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5966 } else {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5967 status = pthread_mutex_unlock(_mutex);
12211
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5968 assert (status == 0, "invariant");
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5969 status = pthread_cond_signal (&_cond[_cur_index]);
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5970 assert (status == 0, "invariant");
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5971 }
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5972 } else {
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5973 pthread_mutex_unlock(_mutex);
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5974 assert (status == 0, "invariant") ;
2e6938dd68f2 6900441: PlatformEvent.park(millis) on Linux could still be affected by changes to the time-of-day clock
dholmes
parents: 12182
diff changeset
5975 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5976 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5977 pthread_mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
5978 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5979 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5980 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5981
a61af66fc99e Initial load
duke
parents:
diff changeset
5982
a61af66fc99e Initial load
duke
parents:
diff changeset
5983 extern char** environ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5984
a61af66fc99e Initial load
duke
parents:
diff changeset
5985 #ifndef __NR_fork
a61af66fc99e Initial load
duke
parents:
diff changeset
5986 #define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57)
a61af66fc99e Initial load
duke
parents:
diff changeset
5987 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5988
a61af66fc99e Initial load
duke
parents:
diff changeset
5989 #ifndef __NR_execve
a61af66fc99e Initial load
duke
parents:
diff changeset
5990 #define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59)
a61af66fc99e Initial load
duke
parents:
diff changeset
5991 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5992
a61af66fc99e Initial load
duke
parents:
diff changeset
5993 // Run the specified command in a separate process. Return its exit value,
a61af66fc99e Initial load
duke
parents:
diff changeset
5994 // or -1 on failure (e.g. can't fork a new process).
a61af66fc99e Initial load
duke
parents:
diff changeset
5995 // Unlike system(), this function can be called from signal handler. It
a61af66fc99e Initial load
duke
parents:
diff changeset
5996 // doesn't block SIGINT et al.
a61af66fc99e Initial load
duke
parents:
diff changeset
5997 int os::fork_and_exec(char* cmd) {
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
5998 const char * argv[4] = {"sh", "-c", cmd, NULL};
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5999
a61af66fc99e Initial load
duke
parents:
diff changeset
6000 // fork() in LinuxThreads/NPTL is not async-safe. It needs to run
a61af66fc99e Initial load
duke
parents:
diff changeset
6001 // pthread_atfork handlers and reset pthread library. All we need is a
a61af66fc99e Initial load
duke
parents:
diff changeset
6002 // separate process to execve. Make a direct syscall to fork process.
a61af66fc99e Initial load
duke
parents:
diff changeset
6003 // On IA64 there's no fork syscall, we have to use fork() and hope for
a61af66fc99e Initial load
duke
parents:
diff changeset
6004 // the best...
a61af66fc99e Initial load
duke
parents:
diff changeset
6005 pid_t pid = NOT_IA64(syscall(__NR_fork);)
a61af66fc99e Initial load
duke
parents:
diff changeset
6006 IA64_ONLY(fork();)
a61af66fc99e Initial load
duke
parents:
diff changeset
6007
a61af66fc99e Initial load
duke
parents:
diff changeset
6008 if (pid < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6009 // fork failed
a61af66fc99e Initial load
duke
parents:
diff changeset
6010 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
6011
a61af66fc99e Initial load
duke
parents:
diff changeset
6012 } else if (pid == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6013 // child process
a61af66fc99e Initial load
duke
parents:
diff changeset
6014
a61af66fc99e Initial load
duke
parents:
diff changeset
6015 // execve() in LinuxThreads will call pthread_kill_other_threads_np()
a61af66fc99e Initial load
duke
parents:
diff changeset
6016 // first to kill every thread on the thread list. Because this list is
a61af66fc99e Initial load
duke
parents:
diff changeset
6017 // not reset by fork() (see notes above), execve() will instead kill
a61af66fc99e Initial load
duke
parents:
diff changeset
6018 // every thread in the parent process. We know this is the only thread
a61af66fc99e Initial load
duke
parents:
diff changeset
6019 // in the new process, so make a system call directly.
a61af66fc99e Initial load
duke
parents:
diff changeset
6020 // IA64 should use normal execve() from glibc to match the glibc fork()
a61af66fc99e Initial load
duke
parents:
diff changeset
6021 // above.
a61af66fc99e Initial load
duke
parents:
diff changeset
6022 NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
199
f139919897d2 6681796: hotspot build failure on gcc 4.2.x (ubuntu 8.04) w/ openjdk 6
xlu
parents: 141
diff changeset
6023 IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6024
a61af66fc99e Initial load
duke
parents:
diff changeset
6025 // execve failed
a61af66fc99e Initial load
duke
parents:
diff changeset
6026 _exit(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
6027
a61af66fc99e Initial load
duke
parents:
diff changeset
6028 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6029 // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
6030 // care about the actual exit code, for now.
a61af66fc99e Initial load
duke
parents:
diff changeset
6031
a61af66fc99e Initial load
duke
parents:
diff changeset
6032 int status;
a61af66fc99e Initial load
duke
parents:
diff changeset
6033
a61af66fc99e Initial load
duke
parents:
diff changeset
6034 // Wait for the child process to exit. This returns immediately if
a61af66fc99e Initial load
duke
parents:
diff changeset
6035 // the child has already exited. */
a61af66fc99e Initial load
duke
parents:
diff changeset
6036 while (waitpid(pid, &status, 0) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6037 switch (errno) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6038 case ECHILD: return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6039 case EINTR: break;
a61af66fc99e Initial load
duke
parents:
diff changeset
6040 default: return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
6041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6043
a61af66fc99e Initial load
duke
parents:
diff changeset
6044 if (WIFEXITED(status)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6045 // The child exited normally; get its exit code.
a61af66fc99e Initial load
duke
parents:
diff changeset
6046 return WEXITSTATUS(status);
a61af66fc99e Initial load
duke
parents:
diff changeset
6047 } else if (WIFSIGNALED(status)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6048 // The child exited because of a signal
a61af66fc99e Initial load
duke
parents:
diff changeset
6049 // The best value to return is 0x80 + signal number,
a61af66fc99e Initial load
duke
parents:
diff changeset
6050 // because that is what all Unix shells do, and because
a61af66fc99e Initial load
duke
parents:
diff changeset
6051 // it allows callers to distinguish between process exit and
a61af66fc99e Initial load
duke
parents:
diff changeset
6052 // process death by signal.
a61af66fc99e Initial load
duke
parents:
diff changeset
6053 return 0x80 + WTERMSIG(status);
a61af66fc99e Initial load
duke
parents:
diff changeset
6054 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6055 // Unknown exit code; pass it through
a61af66fc99e Initial load
duke
parents:
diff changeset
6056 return status;
a61af66fc99e Initial load
duke
parents:
diff changeset
6057 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6059 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6060
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6061 // is_headless_jre()
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6062 //
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6063 // Test for the existence of xawt/libmawt.so or libawt_xawt.so
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6064 // in order to report if we are running in a headless jre
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6065 //
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6066 // Since JDK8 xawt/libmawt.so was moved into the same directory
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6067 // as libawt.so, and renamed libawt_xawt.so
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6068 //
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6069 bool os::is_headless_jre() {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6070 struct stat statbuf;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6071 char buf[MAXPATHLEN];
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6072 char libmawtpath[MAXPATHLEN];
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6073 const char *xawtstr = "/xawt/libmawt.so";
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6074 const char *new_xawtstr = "/libawt_xawt.so";
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6075 char *p;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6076
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6077 // Get path to libjvm.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6078 os::jvm_path(buf, sizeof(buf));
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6079
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6080 // Get rid of libjvm.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6081 p = strrchr(buf, '/');
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6082 if (p == NULL) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6083 else *p = '\0';
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6084
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6085 // Get rid of client or server
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6086 p = strrchr(buf, '/');
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6087 if (p == NULL) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6088 else *p = '\0';
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6089
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6090 // check xawt/libmawt.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6091 strcpy(libmawtpath, buf);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6092 strcat(libmawtpath, xawtstr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6093 if (::stat(libmawtpath, &statbuf) == 0) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6094
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6095 // check libawt_xawt.so
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6096 strcpy(libmawtpath, buf);
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6097 strcat(libmawtpath, new_xawtstr);
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6098 if (::stat(libmawtpath, &statbuf) == 0) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6099
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6100 return true;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6101 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6102
6200
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6103 // Get the default path to the core file
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6104 // Returns the length of the string
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6105 int os::get_core_path(char* buffer, size_t bufferSize) {
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6106 const char* p = get_current_directory(buffer, bufferSize);
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6107
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6108 if (p == NULL) {
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6109 assert(p != NULL, "failed to get current directory");
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6110 return 0;
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6111 }
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6112
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6113 return strlen(buffer);
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6114 }
3802
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6115
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6116 #ifdef JAVASE_EMBEDDED
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6117 //
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6118 // A thread to watch the '/dev/mem_notify' device, which will tell us when the OS is running low on memory.
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6119 //
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6120 MemNotifyThread* MemNotifyThread::_memnotify_thread = NULL;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6121
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6122 // ctor
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6123 //
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6124 MemNotifyThread::MemNotifyThread(int fd): Thread() {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6125 assert(memnotify_thread() == NULL, "we can only allocate one MemNotifyThread");
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6126 _fd = fd;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6127
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6128 if (os::create_thread(this, os::os_thread)) {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6129 _memnotify_thread = this;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6130 os::set_priority(this, NearMaxPriority);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6131 os::start_thread(this);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6132 }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6133 }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6134
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6135 // Where all the work gets done
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6136 //
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6137 void MemNotifyThread::run() {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6138 assert(this == memnotify_thread(), "expected the singleton MemNotifyThread");
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6139
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6140 // Set up the select arguments
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6141 fd_set rfds;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6142 if (_fd != -1) {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6143 FD_ZERO(&rfds);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6144 FD_SET(_fd, &rfds);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6145 }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6146
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6147 // Now wait for the mem_notify device to wake up
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6148 while (1) {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6149 // Wait for the mem_notify device to signal us..
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6150 int rc = select(_fd+1, _fd != -1 ? &rfds : NULL, NULL, NULL, NULL);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6151 if (rc == -1) {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6152 perror("select!\n");
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6153 break;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6154 } else if (rc) {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6155 //ssize_t free_before = os::available_memory();
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6156 //tty->print ("Notified: Free: %dK \n",os::available_memory()/1024);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6157
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6158 // The kernel is telling us there is not much memory left...
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6159 // try to do something about that
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6160
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6161 // If we are not already in a GC, try one.
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6162 if (!Universe::heap()->is_gc_active()) {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6163 Universe::heap()->collect(GCCause::_allocation_failure);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6164
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6165 //ssize_t free_after = os::available_memory();
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6166 //tty->print ("Post-Notify: Free: %dK\n",free_after/1024);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6167 //tty->print ("GC freed: %dK\n", (free_after - free_before)/1024);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6168 }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6169 // We might want to do something like the following if we find the GC's are not helping...
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6170 // Universe::heap()->size_policy()->set_gc_time_limit_exceeded(true);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6171 }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6172 }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6173 }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6174
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6175 //
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6176 // See if the /dev/mem_notify device exists, and if so, start a thread to monitor it.
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6177 //
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6178 void MemNotifyThread::start() {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6179 int fd;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6180 fd = open ("/dev/mem_notify", O_RDONLY, 0);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6181 if (fd < 0) {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6182 return;
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6183 }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6184
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6185 if (memnotify_thread() == NULL) {
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6186 new MemNotifyThread(fd);
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6187 }
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6188 }
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10372
diff changeset
6189
3802
b0b8491925fe 7061212: use o/s low memory notification in embedded builds
jcoomes
parents: 3800
diff changeset
6190 #endif // JAVASE_EMBEDDED
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6191
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6192
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6193 /////////////// Unit tests ///////////////
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6194
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6195 #ifndef PRODUCT
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6196
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6197 #define test_log(...) \
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6198 do {\
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6199 if (VerboseInternalVMTests) { \
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6200 tty->print_cr(__VA_ARGS__); \
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6201 tty->flush(); \
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6202 }\
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6203 } while (false)
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6204
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6205 class TestReserveMemorySpecial : AllStatic {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6206 public:
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6207 static void small_page_write(void* addr, size_t size) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6208 size_t page_size = os::vm_page_size();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6209
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6210 char* end = (char*)addr + size;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6211 for (char* p = (char*)addr; p < end; p += page_size) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6212 *p = 1;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6213 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6214 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6215
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6216 static void test_reserve_memory_special_huge_tlbfs_only(size_t size) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6217 if (!UseHugeTLBFS) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6218 return;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6219 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6220
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6221 test_log("test_reserve_memory_special_huge_tlbfs_only(" SIZE_FORMAT ")", size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6222
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6223 char* addr = os::Linux::reserve_memory_special_huge_tlbfs_only(size, NULL, false);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6224
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6225 if (addr != NULL) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6226 small_page_write(addr, size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6227
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6228 os::Linux::release_memory_special_huge_tlbfs(addr, size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6229 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6230 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6231
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6232 static void test_reserve_memory_special_huge_tlbfs_only() {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6233 if (!UseHugeTLBFS) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6234 return;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6235 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6236
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6237 size_t lp = os::large_page_size();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6238
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6239 for (size_t size = lp; size <= lp * 10; size += lp) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6240 test_reserve_memory_special_huge_tlbfs_only(size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6241 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6242 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6243
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6244 static void test_reserve_memory_special_huge_tlbfs_mixed(size_t size, size_t alignment) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6245 if (!UseHugeTLBFS) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6246 return;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6247 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6248
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6249 test_log("test_reserve_memory_special_huge_tlbfs_mixed(" SIZE_FORMAT ", " SIZE_FORMAT ")",
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6250 size, alignment);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6251
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6252 assert(size >= os::large_page_size(), "Incorrect input to test");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6253
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6254 char* addr = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, NULL, false);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6255
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6256 if (addr != NULL) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6257 small_page_write(addr, size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6258
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6259 os::Linux::release_memory_special_huge_tlbfs(addr, size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6260 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6261 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6262
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6263 static void test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(size_t size) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6264 size_t lp = os::large_page_size();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6265 size_t ag = os::vm_allocation_granularity();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6266
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6267 for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6268 test_reserve_memory_special_huge_tlbfs_mixed(size, alignment);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6269 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6270 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6271
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6272 static void test_reserve_memory_special_huge_tlbfs_mixed() {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6273 size_t lp = os::large_page_size();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6274 size_t ag = os::vm_allocation_granularity();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6275
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6276 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6277 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + ag);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6278 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + lp / 2);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6279 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6280 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + ag);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6281 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 - ag);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6282 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + lp / 2);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6283 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6284 test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10 + lp / 2);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6285 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6286
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6287 static void test_reserve_memory_special_huge_tlbfs() {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6288 if (!UseHugeTLBFS) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6289 return;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6290 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6291
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6292 test_reserve_memory_special_huge_tlbfs_only();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6293 test_reserve_memory_special_huge_tlbfs_mixed();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6294 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6295
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6296 static void test_reserve_memory_special_shm(size_t size, size_t alignment) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6297 if (!UseSHM) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6298 return;
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6299 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6300
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6301 test_log("test_reserve_memory_special_shm(" SIZE_FORMAT ", " SIZE_FORMAT ")", size, alignment);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6302
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6303 char* addr = os::Linux::reserve_memory_special_shm(size, alignment, NULL, false);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6304
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6305 if (addr != NULL) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6306 assert(is_ptr_aligned(addr, alignment), "Check");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6307 assert(is_ptr_aligned(addr, os::large_page_size()), "Check");
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6308
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6309 small_page_write(addr, size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6310
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6311 os::Linux::release_memory_special_shm(addr, size);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6312 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6313 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6314
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6315 static void test_reserve_memory_special_shm() {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6316 size_t lp = os::large_page_size();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6317 size_t ag = os::vm_allocation_granularity();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6318
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6319 for (size_t size = ag; size < lp * 3; size += ag) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6320 for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6321 test_reserve_memory_special_shm(size, alignment);
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6322 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6323 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6324 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6325
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6326 static void test() {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6327 test_reserve_memory_special_huge_tlbfs();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6328 test_reserve_memory_special_shm();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6329 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6330 };
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6331
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6332 void TestReserveMemorySpecial_test() {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6333 TestReserveMemorySpecial::test();
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6334 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6335
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11092
diff changeset
6336 #endif