1 /*
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
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 *
140 // that file provides extensions to the os class and not the
141 // Linux class.
142 static ExtendedPC fetch_frame_from_ucontext(Thread* thread, const ucontext_t* uc,
143 intptr_t** ret_sp, intptr_t** ret_fp);
144
145 static bool get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr);
146
147 // This boolean allows users to forward their own non-matching signals
148 // to JVM_handle_linux_signal, harmlessly.
149 static bool signal_handlers_are_installed;
150
151 static int get_our_sigflags(int);
152 static void set_our_sigflags(int, int);
153 static void signal_sets_init();
154 static void install_signal_handlers();
155 static void set_signal_handler(int, bool);
156 static bool is_sig_ignored(int sig);
157
158 static sigset_t* unblocked_signals();
159 static sigset_t* vm_signals();
160 static sigset_t* allowdebug_blocked_signals();
161
162 // For signal-chaining
163 static struct sigaction *get_chained_signal_action(int sig);
164 static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
165
166 // GNU libc and libpthread version strings
167 static const char *glibc_version() { return _glibc_version; }
168 static const char *libpthread_version() { return _libpthread_version; }
169
170 static void libpthread_init();
171 static bool libnuma_init();
172 static void* libnuma_dlsym(void* handle, const char* name);
173
174 // Return default guard size for the specified thread type
175 static size_t default_guard_size(os::ThreadType thr_type);
176
177 static void capture_initial_stack(size_t max_size);
178
179 // Stack overflow handling
180 static bool manually_expand_stack(JavaThread * t, address addr);
187 static void fast_thread_clock_init(void);
188
189 static int clock_gettime(clockid_t clock_id, struct timespec *tp) {
190 return _clock_gettime ? _clock_gettime(clock_id, tp) : -1;
191 }
192
193 static int pthread_getcpuclockid(pthread_t tid, clockid_t *clock_id) {
194 return _pthread_getcpuclockid ? _pthread_getcpuclockid(tid, clock_id) : -1;
195 }
196
197 static bool supports_fast_thread_cpu_time() {
198 return _supports_fast_thread_cpu_time;
199 }
200
201 static jlong fast_thread_cpu_time(clockid_t clockid);
202
203 static void initialize_os_info();
204 static bool os_version_is_known();
205 static uint32_t os_version();
206
207 // pthread_cond clock suppport
208 private:
209 static pthread_condattr_t _condattr[1];
210
211 public:
212 static pthread_condattr_t* condAttr() { return _condattr; }
213
214 // Stack repair handling
215
216 // none present
217
218 private:
219 typedef int (*sched_getcpu_func_t)(void);
220 typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
221 typedef int (*numa_max_node_func_t)(void);
222 typedef int (*numa_available_func_t)(void);
223 typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node);
224 typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask);
225 typedef void (*numa_set_bind_policy_func_t)(int policy);
226
227 static sched_getcpu_func_t _sched_getcpu;
228 static numa_node_to_cpus_func_t _numa_node_to_cpus;
229 static numa_max_node_func_t _numa_max_node;
230 static numa_available_func_t _numa_available;
231 static numa_tonode_memory_func_t _numa_tonode_memory;
232 static numa_interleave_memory_func_t _numa_interleave_memory;
233 static numa_set_bind_policy_func_t _numa_set_bind_policy;
246 static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
247 static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {
248 return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1;
249 }
250 static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; }
251 static int numa_available() { return _numa_available != NULL ? _numa_available() : -1; }
252 static int numa_tonode_memory(void *start, size_t size, int node) {
253 return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1;
254 }
255 static void numa_interleave_memory(void *start, size_t size) {
256 if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) {
257 _numa_interleave_memory(start, size, _numa_all_nodes);
258 }
259 }
260 static void numa_set_bind_policy(int policy) {
261 if (_numa_set_bind_policy != NULL) {
262 _numa_set_bind_policy(policy);
263 }
264 }
265 static int get_node_by_cpu(int cpu_id);
266 };
267
268
269 class PlatformEvent : public CHeapObj<mtInternal> {
270 private:
271 double CachePad[4]; // increase odds that _mutex is sole occupant of cache line
272 volatile int _Event;
273 volatile int _nParked;
274 pthread_mutex_t _mutex[1];
275 pthread_cond_t _cond[1];
276 double PostPad[2];
277 Thread * _Assoc;
278
279 public: // TODO-FIXME: make dtor private
280 ~PlatformEvent() { guarantee(0, "invariant"); }
281
282 public:
283 PlatformEvent() {
284 int status;
285 status = pthread_cond_init(_cond, os::Linux::condAttr());
286 assert_status(status == 0, status, "cond_init");
287 status = pthread_mutex_init(_mutex, NULL);
288 assert_status(status == 0, status, "mutex_init");
289 _Event = 0;
290 _nParked = 0;
291 _Assoc = NULL;
292 }
293
294 // Use caution with reset() and fired() -- they may require MEMBARs
295 void reset() { _Event = 0; }
296 int fired() { return _Event; }
297 void park();
298 void unpark();
299 int park(jlong millis); // relative timed-wait only
300 void SetAssociation(Thread * a) { _Assoc = a; }
301 };
302
303 class PlatformParker : public CHeapObj<mtInternal> {
304 protected:
305 enum {
306 REL_INDEX = 0,
307 ABS_INDEX = 1
308 };
309 int _cur_index; // which cond is in use: -1, 0, 1
310 pthread_mutex_t _mutex[1];
311 pthread_cond_t _cond[2]; // one for relative times and one for abs.
312
313 public: // TODO-FIXME: make dtor private
314 ~PlatformParker() { guarantee(0, "invariant"); }
315
316 public:
317 PlatformParker() {
318 int status;
319 status = pthread_cond_init(&_cond[REL_INDEX], os::Linux::condAttr());
320 assert_status(status == 0, status, "cond_init rel");
321 status = pthread_cond_init(&_cond[ABS_INDEX], NULL);
322 assert_status(status == 0, status, "cond_init abs");
323 status = pthread_mutex_init(_mutex, NULL);
324 assert_status(status == 0, status, "mutex_init");
325 _cur_index = -1; // mark as unused
326 }
327 };
328
329 #endif // OS_LINUX_VM_OS_LINUX_HPP
|
1 /*
2 * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
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 *
140 // that file provides extensions to the os class and not the
141 // Linux class.
142 static ExtendedPC fetch_frame_from_ucontext(Thread* thread, const ucontext_t* uc,
143 intptr_t** ret_sp, intptr_t** ret_fp);
144
145 static bool get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr);
146
147 // This boolean allows users to forward their own non-matching signals
148 // to JVM_handle_linux_signal, harmlessly.
149 static bool signal_handlers_are_installed;
150
151 static int get_our_sigflags(int);
152 static void set_our_sigflags(int, int);
153 static void signal_sets_init();
154 static void install_signal_handlers();
155 static void set_signal_handler(int, bool);
156 static bool is_sig_ignored(int sig);
157
158 static sigset_t* unblocked_signals();
159 static sigset_t* vm_signals();
160
161 // For signal-chaining
162 static struct sigaction *get_chained_signal_action(int sig);
163 static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
164
165 // GNU libc and libpthread version strings
166 static const char *glibc_version() { return _glibc_version; }
167 static const char *libpthread_version() { return _libpthread_version; }
168
169 static void libpthread_init();
170 static bool libnuma_init();
171 static void* libnuma_dlsym(void* handle, const char* name);
172
173 // Return default guard size for the specified thread type
174 static size_t default_guard_size(os::ThreadType thr_type);
175
176 static void capture_initial_stack(size_t max_size);
177
178 // Stack overflow handling
179 static bool manually_expand_stack(JavaThread * t, address addr);
186 static void fast_thread_clock_init(void);
187
188 static int clock_gettime(clockid_t clock_id, struct timespec *tp) {
189 return _clock_gettime ? _clock_gettime(clock_id, tp) : -1;
190 }
191
192 static int pthread_getcpuclockid(pthread_t tid, clockid_t *clock_id) {
193 return _pthread_getcpuclockid ? _pthread_getcpuclockid(tid, clock_id) : -1;
194 }
195
196 static bool supports_fast_thread_cpu_time() {
197 return _supports_fast_thread_cpu_time;
198 }
199
200 static jlong fast_thread_cpu_time(clockid_t clockid);
201
202 static void initialize_os_info();
203 static bool os_version_is_known();
204 static uint32_t os_version();
205
206 // Stack repair handling
207
208 // none present
209
210 private:
211 typedef int (*sched_getcpu_func_t)(void);
212 typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
213 typedef int (*numa_max_node_func_t)(void);
214 typedef int (*numa_available_func_t)(void);
215 typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node);
216 typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask);
217 typedef void (*numa_set_bind_policy_func_t)(int policy);
218
219 static sched_getcpu_func_t _sched_getcpu;
220 static numa_node_to_cpus_func_t _numa_node_to_cpus;
221 static numa_max_node_func_t _numa_max_node;
222 static numa_available_func_t _numa_available;
223 static numa_tonode_memory_func_t _numa_tonode_memory;
224 static numa_interleave_memory_func_t _numa_interleave_memory;
225 static numa_set_bind_policy_func_t _numa_set_bind_policy;
238 static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
239 static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {
240 return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1;
241 }
242 static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; }
243 static int numa_available() { return _numa_available != NULL ? _numa_available() : -1; }
244 static int numa_tonode_memory(void *start, size_t size, int node) {
245 return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1;
246 }
247 static void numa_interleave_memory(void *start, size_t size) {
248 if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) {
249 _numa_interleave_memory(start, size, _numa_all_nodes);
250 }
251 }
252 static void numa_set_bind_policy(int policy) {
253 if (_numa_set_bind_policy != NULL) {
254 _numa_set_bind_policy(policy);
255 }
256 }
257 static int get_node_by_cpu(int cpu_id);
258 };
259
260 #endif // OS_LINUX_VM_OS_LINUX_HPP
|