1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/os/bsd/vm/os_bsd.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,253 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef OS_BSD_VM_OS_BSD_HPP 1.29 +#define OS_BSD_VM_OS_BSD_HPP 1.30 + 1.31 +// Bsd_OS defines the interface to Bsd operating systems 1.32 + 1.33 +// Information about the protection of the page at address '0' on this os. 1.34 +static bool zero_page_read_protected() { return true; } 1.35 + 1.36 +/* pthread_getattr_np comes with BsdThreads-0.9-7 on RedHat 7.1 */ 1.37 +typedef int (*pthread_getattr_func_type) (pthread_t, pthread_attr_t *); 1.38 + 1.39 +#ifdef __APPLE__ 1.40 +// Mac OS X doesn't support clock_gettime. Stub out the type, it is 1.41 +// unused 1.42 +typedef int clockid_t; 1.43 +#endif 1.44 + 1.45 +class Bsd { 1.46 + friend class os; 1.47 + 1.48 + // For signal-chaining 1.49 +#define MAXSIGNUM 32 1.50 + static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions 1.51 + static unsigned int sigs; // mask of signals that have 1.52 + // preinstalled signal handlers 1.53 + static bool libjsig_is_loaded; // libjsig that interposes sigaction(), 1.54 + // __sigaction(), signal() is loaded 1.55 + static struct sigaction *(*get_signal_action)(int); 1.56 + static struct sigaction *get_preinstalled_handler(int); 1.57 + static void save_preinstalled_handler(int, struct sigaction&); 1.58 + 1.59 + static void check_signal_handler(int sig); 1.60 + 1.61 + // For signal flags diagnostics 1.62 + static int sigflags[MAXSIGNUM]; 1.63 + 1.64 +#ifdef __APPLE__ 1.65 + // mach_absolute_time 1.66 + static mach_timebase_info_data_t _timebase_info; 1.67 + static volatile uint64_t _max_abstime; 1.68 +#else 1.69 + static int (*_clock_gettime)(clockid_t, struct timespec *); 1.70 +#endif 1.71 + 1.72 + static GrowableArray<int>* _cpu_to_node; 1.73 + 1.74 + protected: 1.75 + 1.76 + static julong _physical_memory; 1.77 + static pthread_t _main_thread; 1.78 + static int _page_size; 1.79 + 1.80 + static julong available_memory(); 1.81 + static julong physical_memory() { return _physical_memory; } 1.82 + static void initialize_system_info(); 1.83 + 1.84 + static bool supports_variable_stack_size(); 1.85 + 1.86 + static void rebuild_cpu_to_node_map(); 1.87 + static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; } 1.88 + 1.89 + static bool hugetlbfs_sanity_check(bool warn, size_t page_size); 1.90 + 1.91 + public: 1.92 + 1.93 + static void init_thread_fpu_state(); 1.94 + static pthread_t main_thread(void) { return _main_thread; } 1.95 + 1.96 + static void hotspot_sigmask(Thread* thread); 1.97 + 1.98 + static bool is_initial_thread(void); 1.99 + static pid_t gettid(); 1.100 + 1.101 + static int page_size(void) { return _page_size; } 1.102 + static void set_page_size(int val) { _page_size = val; } 1.103 + 1.104 + static address ucontext_get_pc(ucontext_t* uc); 1.105 + static intptr_t* ucontext_get_sp(ucontext_t* uc); 1.106 + static intptr_t* ucontext_get_fp(ucontext_t* uc); 1.107 + 1.108 + // For Analyzer Forte AsyncGetCallTrace profiling support: 1.109 + // 1.110 + // This interface should be declared in os_bsd_i486.hpp, but 1.111 + // that file provides extensions to the os class and not the 1.112 + // Bsd class. 1.113 + static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc, 1.114 + intptr_t** ret_sp, intptr_t** ret_fp); 1.115 + 1.116 + // This boolean allows users to forward their own non-matching signals 1.117 + // to JVM_handle_bsd_signal, harmlessly. 1.118 + static bool signal_handlers_are_installed; 1.119 + 1.120 + static int get_our_sigflags(int); 1.121 + static void set_our_sigflags(int, int); 1.122 + static void signal_sets_init(); 1.123 + static void install_signal_handlers(); 1.124 + static void set_signal_handler(int, bool); 1.125 + static bool is_sig_ignored(int sig); 1.126 + 1.127 + static sigset_t* unblocked_signals(); 1.128 + static sigset_t* vm_signals(); 1.129 + static sigset_t* allowdebug_blocked_signals(); 1.130 + 1.131 + // For signal-chaining 1.132 + static struct sigaction *get_chained_signal_action(int sig); 1.133 + static bool chained_handler(int sig, siginfo_t* siginfo, void* context); 1.134 + 1.135 + // Minimum stack size a thread can be created with (allowing 1.136 + // the VM to completely create the thread and enter user code) 1.137 + static size_t min_stack_allowed; 1.138 + 1.139 + // Return default stack size or guard size for the specified thread type 1.140 + static size_t default_stack_size(os::ThreadType thr_type); 1.141 + static size_t default_guard_size(os::ThreadType thr_type); 1.142 + 1.143 + // Real-time clock functions 1.144 + static void clock_init(void); 1.145 + 1.146 + static inline bool supports_monotonic_clock() { 1.147 +#ifdef __APPLE__ 1.148 + return true; 1.149 +#else 1.150 + return _clock_gettime != NULL; 1.151 +#endif 1.152 + } 1.153 + 1.154 + // Stack repair handling 1.155 + 1.156 + // none present 1.157 + 1.158 + // BsdThreads work-around for 6292965 1.159 + static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime); 1.160 + 1.161 +private: 1.162 + typedef int (*sched_getcpu_func_t)(void); 1.163 + typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen); 1.164 + typedef int (*numa_max_node_func_t)(void); 1.165 + typedef int (*numa_available_func_t)(void); 1.166 + typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node); 1.167 + typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask); 1.168 + 1.169 + static sched_getcpu_func_t _sched_getcpu; 1.170 + static numa_node_to_cpus_func_t _numa_node_to_cpus; 1.171 + static numa_max_node_func_t _numa_max_node; 1.172 + static numa_available_func_t _numa_available; 1.173 + static numa_tonode_memory_func_t _numa_tonode_memory; 1.174 + static numa_interleave_memory_func_t _numa_interleave_memory; 1.175 + static unsigned long* _numa_all_nodes; 1.176 + 1.177 + static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; } 1.178 + static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; } 1.179 + static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; } 1.180 + static void set_numa_available(numa_available_func_t func) { _numa_available = func; } 1.181 + static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } 1.182 + static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; } 1.183 + static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; } 1.184 +public: 1.185 + static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; } 1.186 + static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) { 1.187 + return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1; 1.188 + } 1.189 + static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; } 1.190 + static int numa_available() { return _numa_available != NULL ? _numa_available() : -1; } 1.191 + static int numa_tonode_memory(void *start, size_t size, int node) { 1.192 + return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1; 1.193 + } 1.194 + static void numa_interleave_memory(void *start, size_t size) { 1.195 + if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) { 1.196 + _numa_interleave_memory(start, size, _numa_all_nodes); 1.197 + } 1.198 + } 1.199 + static int get_node_by_cpu(int cpu_id); 1.200 +}; 1.201 + 1.202 + 1.203 +class PlatformEvent : public CHeapObj<mtInternal> { 1.204 + private: 1.205 + double CachePad [4] ; // increase odds that _mutex is sole occupant of cache line 1.206 + volatile int _Event ; 1.207 + volatile int _nParked ; 1.208 + pthread_mutex_t _mutex [1] ; 1.209 + pthread_cond_t _cond [1] ; 1.210 + double PostPad [2] ; 1.211 + Thread * _Assoc ; 1.212 + 1.213 + public: // TODO-FIXME: make dtor private 1.214 + ~PlatformEvent() { guarantee (0, "invariant") ; } 1.215 + 1.216 + public: 1.217 + PlatformEvent() { 1.218 + int status; 1.219 + status = pthread_cond_init (_cond, NULL); 1.220 + assert_status(status == 0, status, "cond_init"); 1.221 + status = pthread_mutex_init (_mutex, NULL); 1.222 + assert_status(status == 0, status, "mutex_init"); 1.223 + _Event = 0 ; 1.224 + _nParked = 0 ; 1.225 + _Assoc = NULL ; 1.226 + } 1.227 + 1.228 + // Use caution with reset() and fired() -- they may require MEMBARs 1.229 + void reset() { _Event = 0 ; } 1.230 + int fired() { return _Event; } 1.231 + void park () ; 1.232 + void unpark () ; 1.233 + int TryPark () ; 1.234 + int park (jlong millis) ; 1.235 + void SetAssociation (Thread * a) { _Assoc = a ; } 1.236 +}; 1.237 + 1.238 +class PlatformParker : public CHeapObj<mtInternal> { 1.239 + protected: 1.240 + pthread_mutex_t _mutex [1] ; 1.241 + pthread_cond_t _cond [1] ; 1.242 + 1.243 + public: // TODO-FIXME: make dtor private 1.244 + ~PlatformParker() { guarantee (0, "invariant") ; } 1.245 + 1.246 + public: 1.247 + PlatformParker() { 1.248 + int status; 1.249 + status = pthread_cond_init (_cond, NULL); 1.250 + assert_status(status == 0, status, "cond_init"); 1.251 + status = pthread_mutex_init (_mutex, NULL); 1.252 + assert_status(status == 0, status, "mutex_init"); 1.253 + } 1.254 +}; 1.255 + 1.256 +#endif // OS_BSD_VM_OS_BSD_HPP