Mercurial > hg > graal-jvmci-8
annotate src/os/bsd/vm/os_bsd.hpp @ 8854:754c24457b20
7112912: Message "Error occurred during initialization of VM" on boxes with lots of RAM
Summary: Ergonomics now also takes available virtual memory into account when deciding for a heap size. The helper method to determine the maximum allocatable memory block now uses the appropriate OS specific calls to retrieve available virtual memory for the java process. In 32 bit environments this method now also searches for the maximum actually reservable amount of memory. Merge previously separate implementations for Linux/BSD/Solaris into a single method.
Reviewed-by: jmasa, tamao
author | tschatzl |
---|---|
date | Wed, 27 Mar 2013 19:21:18 +0100 |
parents | 63e54c37ac64 |
children | f2110083203d |
rev | line source |
---|---|
3960 | 1 /* |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. |
3960 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
25 #ifndef OS_BSD_VM_OS_BSD_HPP | |
26 #define OS_BSD_VM_OS_BSD_HPP | |
27 | |
28 // Bsd_OS defines the interface to Bsd operating systems | |
29 | |
30 /* pthread_getattr_np comes with BsdThreads-0.9-7 on RedHat 7.1 */ | |
31 typedef int (*pthread_getattr_func_type) (pthread_t, pthread_attr_t *); | |
32 | |
33 #ifdef __APPLE__ | |
34 // Mac OS X doesn't support clock_gettime. Stub out the type, it is | |
35 // unused | |
36 typedef int clockid_t; | |
37 #endif | |
38 | |
39 class Bsd { | |
40 friend class os; | |
41 | |
42 // For signal-chaining | |
43 #define MAXSIGNUM 32 | |
44 static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions | |
45 static unsigned int sigs; // mask of signals that have | |
46 // preinstalled signal handlers | |
47 static bool libjsig_is_loaded; // libjsig that interposes sigaction(), | |
48 // __sigaction(), signal() is loaded | |
49 static struct sigaction *(*get_signal_action)(int); | |
50 static struct sigaction *get_preinstalled_handler(int); | |
51 static void save_preinstalled_handler(int, struct sigaction&); | |
52 | |
53 static void check_signal_handler(int sig); | |
54 | |
55 // For signal flags diagnostics | |
56 static int sigflags[MAXSIGNUM]; | |
57 | |
58 static int (*_clock_gettime)(clockid_t, struct timespec *); | |
59 | |
60 static GrowableArray<int>* _cpu_to_node; | |
61 | |
62 protected: | |
63 | |
64 static julong _physical_memory; | |
65 static pthread_t _main_thread; | |
66 static int _page_size; | |
67 | |
68 static julong available_memory(); | |
69 static julong physical_memory() { return _physical_memory; } | |
70 static void initialize_system_info(); | |
71 | |
72 static bool supports_variable_stack_size(); | |
73 | |
74 static void rebuild_cpu_to_node_map(); | |
75 static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; } | |
76 | |
77 static bool hugetlbfs_sanity_check(bool warn, size_t page_size); | |
78 | |
79 public: | |
80 | |
81 static void init_thread_fpu_state(); | |
82 static pthread_t main_thread(void) { return _main_thread; } | |
83 | |
84 static void hotspot_sigmask(Thread* thread); | |
85 | |
86 static bool is_initial_thread(void); | |
87 | |
88 static int page_size(void) { return _page_size; } | |
89 static void set_page_size(int val) { _page_size = val; } | |
90 | |
91 static address ucontext_get_pc(ucontext_t* uc); | |
92 static intptr_t* ucontext_get_sp(ucontext_t* uc); | |
93 static intptr_t* ucontext_get_fp(ucontext_t* uc); | |
94 | |
95 // For Analyzer Forte AsyncGetCallTrace profiling support: | |
96 // | |
97 // This interface should be declared in os_bsd_i486.hpp, but | |
98 // that file provides extensions to the os class and not the | |
99 // Bsd class. | |
100 static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc, | |
101 intptr_t** ret_sp, intptr_t** ret_fp); | |
102 | |
103 // This boolean allows users to forward their own non-matching signals | |
104 // to JVM_handle_bsd_signal, harmlessly. | |
105 static bool signal_handlers_are_installed; | |
106 | |
107 static int get_our_sigflags(int); | |
108 static void set_our_sigflags(int, int); | |
109 static void signal_sets_init(); | |
110 static void install_signal_handlers(); | |
111 static void set_signal_handler(int, bool); | |
112 static bool is_sig_ignored(int sig); | |
113 | |
114 static sigset_t* unblocked_signals(); | |
115 static sigset_t* vm_signals(); | |
116 static sigset_t* allowdebug_blocked_signals(); | |
117 | |
118 // For signal-chaining | |
119 static struct sigaction *get_chained_signal_action(int sig); | |
120 static bool chained_handler(int sig, siginfo_t* siginfo, void* context); | |
121 | |
122 // Minimum stack size a thread can be created with (allowing | |
123 // the VM to completely create the thread and enter user code) | |
124 static size_t min_stack_allowed; | |
125 | |
126 // Return default stack size or guard size for the specified thread type | |
127 static size_t default_stack_size(os::ThreadType thr_type); | |
128 static size_t default_guard_size(os::ThreadType thr_type); | |
129 | |
130 // Real-time clock functions | |
131 static void clock_init(void); | |
132 | |
6630
fa9253dcd4df
7194409: os::javaTimeNanos() shows hot on CPU_CLK_UNHALTED profiles
johnc
parents:
6197
diff
changeset
|
133 static inline bool supports_monotonic_clock() { |
3960 | 134 return _clock_gettime != NULL; |
135 } | |
136 | |
137 static int clock_gettime(clockid_t clock_id, struct timespec *tp) { | |
138 return _clock_gettime ? _clock_gettime(clock_id, tp) : -1; | |
139 } | |
140 | |
141 // Stack repair handling | |
142 | |
143 // none present | |
144 | |
145 // BsdThreads work-around for 6292965 | |
146 static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime); | |
147 | |
148 | |
149 // Bsd suspend/resume support - this helper is a shadow of its former | |
150 // self now that low-level suspension is barely used, and old workarounds | |
151 // for BsdThreads are no longer needed. | |
152 class SuspendResume { | |
153 private: | |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
154 volatile int _suspend_action; |
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
155 volatile jint _state; |
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
156 public: |
3960 | 157 // values for suspend_action: |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
158 enum { |
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
159 SR_NONE = 0x00, |
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
160 SR_SUSPEND = 0x01, // suspend request |
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
161 SR_CONTINUE = 0x02, // resume request |
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
162 SR_SUSPENDED = 0x20 // values for _state: + SR_NONE |
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
163 }; |
3960 | 164 |
165 SuspendResume() { _suspend_action = SR_NONE; _state = SR_NONE; } | |
166 | |
167 int suspend_action() const { return _suspend_action; } | |
168 void set_suspend_action(int x) { _suspend_action = x; } | |
169 | |
170 // atomic updates for _state | |
8675
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
171 inline void set_suspended(); |
63e54c37ac64
8008959: Fix non-PCH build on Linux, Windows and MacOS X
simonis
parents:
6918
diff
changeset
|
172 inline void clear_suspended(); |
3960 | 173 bool is_suspended() { return _state & SR_SUSPENDED; } |
174 | |
175 #undef SR_SUSPENDED | |
176 }; | |
177 | |
178 private: | |
179 typedef int (*sched_getcpu_func_t)(void); | |
180 typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen); | |
181 typedef int (*numa_max_node_func_t)(void); | |
182 typedef int (*numa_available_func_t)(void); | |
183 typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node); | |
184 typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask); | |
185 | |
186 static sched_getcpu_func_t _sched_getcpu; | |
187 static numa_node_to_cpus_func_t _numa_node_to_cpus; | |
188 static numa_max_node_func_t _numa_max_node; | |
189 static numa_available_func_t _numa_available; | |
190 static numa_tonode_memory_func_t _numa_tonode_memory; | |
191 static numa_interleave_memory_func_t _numa_interleave_memory; | |
192 static unsigned long* _numa_all_nodes; | |
193 | |
194 static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; } | |
195 static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; } | |
196 static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; } | |
197 static void set_numa_available(numa_available_func_t func) { _numa_available = func; } | |
198 static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } | |
199 static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; } | |
200 static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; } | |
201 public: | |
202 static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; } | |
203 static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) { | |
204 return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1; | |
205 } | |
206 static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; } | |
207 static int numa_available() { return _numa_available != NULL ? _numa_available() : -1; } | |
208 static int numa_tonode_memory(void *start, size_t size, int node) { | |
209 return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1; | |
210 } | |
211 static void numa_interleave_memory(void *start, size_t size) { | |
212 if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) { | |
213 _numa_interleave_memory(start, size, _numa_all_nodes); | |
214 } | |
215 } | |
216 static int get_node_by_cpu(int cpu_id); | |
217 }; | |
218 | |
219 | |
6197 | 220 class PlatformEvent : public CHeapObj<mtInternal> { |
3960 | 221 private: |
222 double CachePad [4] ; // increase odds that _mutex is sole occupant of cache line | |
223 volatile int _Event ; | |
224 volatile int _nParked ; | |
225 pthread_mutex_t _mutex [1] ; | |
226 pthread_cond_t _cond [1] ; | |
227 double PostPad [2] ; | |
228 Thread * _Assoc ; | |
229 | |
230 public: // TODO-FIXME: make dtor private | |
231 ~PlatformEvent() { guarantee (0, "invariant") ; } | |
232 | |
233 public: | |
234 PlatformEvent() { | |
235 int status; | |
236 status = pthread_cond_init (_cond, NULL); | |
237 assert_status(status == 0, status, "cond_init"); | |
238 status = pthread_mutex_init (_mutex, NULL); | |
239 assert_status(status == 0, status, "mutex_init"); | |
240 _Event = 0 ; | |
241 _nParked = 0 ; | |
242 _Assoc = NULL ; | |
243 } | |
244 | |
245 // Use caution with reset() and fired() -- they may require MEMBARs | |
246 void reset() { _Event = 0 ; } | |
247 int fired() { return _Event; } | |
248 void park () ; | |
249 void unpark () ; | |
250 int TryPark () ; | |
251 int park (jlong millis) ; | |
252 void SetAssociation (Thread * a) { _Assoc = a ; } | |
253 } ; | |
254 | |
6197 | 255 class PlatformParker : public CHeapObj<mtInternal> { |
3960 | 256 protected: |
257 pthread_mutex_t _mutex [1] ; | |
258 pthread_cond_t _cond [1] ; | |
259 | |
260 public: // TODO-FIXME: make dtor private | |
261 ~PlatformParker() { guarantee (0, "invariant") ; } | |
262 | |
263 public: | |
264 PlatformParker() { | |
265 int status; | |
266 status = pthread_cond_init (_cond, NULL); | |
267 assert_status(status == 0, status, "cond_init"); | |
268 status = pthread_mutex_init (_mutex, NULL); | |
269 assert_status(status == 0, status, "mutex_init"); | |
270 } | |
271 } ; | |
272 | |
273 #endif // OS_BSD_VM_OS_BSD_HPP |