os_bsd.hpp revision 6604:a2f5d920638e
1234449Sobrien/* 268349Sobrien * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. 3159764Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4234449Sobrien * 5133359Sobrien * This code is free software; you can redistribute it and/or modify it 6133359Sobrien * under the terms of the GNU General Public License version 2 only, as 7133359Sobrien * published by the Free Software Foundation. 868349Sobrien * 9133359Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT 10133359Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11133359Sobrien * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12133359Sobrien * version 2 for more details (a copy is included in the LICENSE file that 1368349Sobrien * accompanied this code). 14234449Sobrien * 15234449Sobrien * You should have received a copy of the GNU General Public License version 16234449Sobrien * 2 along with this work; if not, write to the Free Software Foundation, 17234449Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18234449Sobrien * 19234449Sobrien * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20234449Sobrien * or visit www.oracle.com if you need additional information or have any 21175296Sobrien * questions. 22234449Sobrien * 23139368Sobrien */ 24159764Sobrien 25159764Sobrien#ifndef OS_BSD_VM_OS_BSD_HPP 26159764Sobrien#define OS_BSD_VM_OS_BSD_HPP 27159764Sobrien 28159764Sobrien// Bsd_OS defines the interface to Bsd operating systems 29159764Sobrien 30159764Sobrien// Information about the protection of the page at address '0' on this os. 31159764Sobrienstatic bool zero_page_read_protected() { return true; } 32175296Sobrien 33175296Sobrien/* pthread_getattr_np comes with BsdThreads-0.9-7 on RedHat 7.1 */ 34234449Sobrientypedef int (*pthread_getattr_func_type) (pthread_t, pthread_attr_t *); 35175296Sobrien 36175296Sobrien#ifdef __APPLE__ 37234449Sobrien// Mac OS X doesn't support clock_gettime. Stub out the type, it is 38175296Sobrien// unused 39175296Sobrientypedef int clockid_t; 40159764Sobrien#endif 41175296Sobrien 42175296Sobrienclass Bsd { 43175296Sobrien friend class os; 44175296Sobrien 45175296Sobrien // For signal-chaining 46175296Sobrien#define MAXSIGNUM 32 47175296Sobrien static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions 48159764Sobrien static unsigned int sigs; // mask of signals that have 49159764Sobrien // preinstalled signal handlers 50175296Sobrien static bool libjsig_is_loaded; // libjsig that interposes sigaction(), 51234449Sobrien // __sigaction(), signal() is loaded 52159764Sobrien static struct sigaction *(*get_signal_action)(int); 53234449Sobrien static struct sigaction *get_preinstalled_handler(int); 54234449Sobrien static void save_preinstalled_handler(int, struct sigaction&); 55234449Sobrien 56234449Sobrien static void check_signal_handler(int sig); 57159764Sobrien 58159764Sobrien // For signal flags diagnostics 59159764Sobrien static int sigflags[MAXSIGNUM]; 60159764Sobrien 61139368Sobrien#ifdef __APPLE__ 62159764Sobrien // mach_absolute_time 63159764Sobrien static mach_timebase_info_data_t _timebase_info; 64159764Sobrien static volatile uint64_t _max_abstime; 65159764Sobrien#else 66159764Sobrien static int (*_clock_gettime)(clockid_t, struct timespec *); 67159764Sobrien#endif 68159764Sobrien 69139368Sobrien static GrowableArray<int>* _cpu_to_node; 70159764Sobrien 71159764Sobrien protected: 72159764Sobrien 73159764Sobrien static julong _physical_memory; 74159764Sobrien static pthread_t _main_thread; 75159764Sobrien static int _page_size; 76159764Sobrien 77139368Sobrien static julong available_memory(); 78159764Sobrien static julong physical_memory() { return _physical_memory; } 79159764Sobrien static void initialize_system_info(); 80159764Sobrien 81159764Sobrien static bool supports_variable_stack_size(); 82159764Sobrien 83159764Sobrien static void rebuild_cpu_to_node_map(); 84139368Sobrien static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; } 85159764Sobrien 86159764Sobrien static bool hugetlbfs_sanity_check(bool warn, size_t page_size); 87159764Sobrien 88159764Sobrien public: 89139368Sobrien 90159764Sobrien static void init_thread_fpu_state(); 91159764Sobrien static pthread_t main_thread(void) { return _main_thread; } 92159764Sobrien 93159764Sobrien static void hotspot_sigmask(Thread* thread); 94159764Sobrien 95159764Sobrien static bool is_initial_thread(void); 96159764Sobrien static pid_t gettid(); 97159764Sobrien 98159764Sobrien static int page_size(void) { return _page_size; } 99139368Sobrien static void set_page_size(int val) { _page_size = val; } 100159764Sobrien 101159764Sobrien static address ucontext_get_pc(ucontext_t* uc); 102159764Sobrien static intptr_t* ucontext_get_sp(ucontext_t* uc); 103159764Sobrien static intptr_t* ucontext_get_fp(ucontext_t* uc); 104159764Sobrien 105159764Sobrien // For Analyzer Forte AsyncGetCallTrace profiling support: 106159764Sobrien // 107159764Sobrien // This interface should be declared in os_bsd_i486.hpp, but 108159764Sobrien // that file provides extensions to the os class and not the 109159764Sobrien // Bsd class. 110159764Sobrien static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc, 111159764Sobrien intptr_t** ret_sp, intptr_t** ret_fp); 112159764Sobrien 113234449Sobrien // This boolean allows users to forward their own non-matching signals 114159764Sobrien // to JVM_handle_bsd_signal, harmlessly. 115139368Sobrien static bool signal_handlers_are_installed; 116159764Sobrien 117159764Sobrien static int get_our_sigflags(int); 118159764Sobrien static void set_our_sigflags(int, int); 119159764Sobrien static void signal_sets_init(); 120234449Sobrien static void install_signal_handlers(); 121159764Sobrien static void set_signal_handler(int, bool); 122159764Sobrien static bool is_sig_ignored(int sig); 123159764Sobrien 124159764Sobrien static sigset_t* unblocked_signals(); 125159764Sobrien static sigset_t* vm_signals(); 126159764Sobrien static sigset_t* allowdebug_blocked_signals(); 127159764Sobrien 128159764Sobrien // For signal-chaining 129175296Sobrien static struct sigaction *get_chained_signal_action(int sig); 130175296Sobrien static bool chained_handler(int sig, siginfo_t* siginfo, void* context); 131175296Sobrien 132175296Sobrien // Minimum stack size a thread can be created with (allowing 133234449Sobrien // the VM to completely create the thread and enter user code) 134159764Sobrien static size_t min_stack_allowed; 135159764Sobrien 136159764Sobrien // Return default stack size or guard size for the specified thread type 137159764Sobrien static size_t default_stack_size(os::ThreadType thr_type); 138159764Sobrien static size_t default_guard_size(os::ThreadType thr_type); 139159764Sobrien 140159764Sobrien // Real-time clock functions 141159764Sobrien static void clock_init(void); 142159764Sobrien 143159764Sobrien // Stack repair handling 144159764Sobrien 145159764Sobrien // none present 146159764Sobrien 147234449Sobrien // BsdThreads work-around for 6292965 148159764Sobrien static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime); 149139368Sobrien 150159764Sobrienprivate: 151159764Sobrien typedef int (*sched_getcpu_func_t)(void); 152159764Sobrien typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen); 153139368Sobrien typedef int (*numa_max_node_func_t)(void); 154234449Sobrien typedef int (*numa_available_func_t)(void); 155139368Sobrien typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node); 156159764Sobrien typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask); 157159764Sobrien 158159764Sobrien static sched_getcpu_func_t _sched_getcpu; 159159764Sobrien static numa_node_to_cpus_func_t _numa_node_to_cpus; 160159764Sobrien static numa_max_node_func_t _numa_max_node; 161139368Sobrien static numa_available_func_t _numa_available; 162139368Sobrien static numa_tonode_memory_func_t _numa_tonode_memory; 163159764Sobrien static numa_interleave_memory_func_t _numa_interleave_memory; 164159764Sobrien static unsigned long* _numa_all_nodes; 165159764Sobrien 166159764Sobrien static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; } 167159764Sobrien static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; } 168159764Sobrien static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; } 169159764Sobrien static void set_numa_available(numa_available_func_t func) { _numa_available = func; } 170159764Sobrien static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; } 171159764Sobrien static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; } 172159764Sobrien static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; } 173159764Sobrienpublic: 174159764Sobrien static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; } 175159764Sobrien static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) { 176159764Sobrien return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1; 177159764Sobrien } 178139368Sobrien static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; } 179159764Sobrien static int numa_available() { return _numa_available != NULL ? _numa_available() : -1; } 180159764Sobrien static int numa_tonode_memory(void *start, size_t size, int node) { 181159764Sobrien return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1; 182175296Sobrien } 183159764Sobrien static void numa_interleave_memory(void *start, size_t size) { 184159764Sobrien if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) { 185133359Sobrien _numa_interleave_memory(start, size, _numa_all_nodes); 186159764Sobrien } 187159764Sobrien } 188159764Sobrien static int get_node_by_cpu(int cpu_id); 189159764Sobrien}; 190159764Sobrien 191159764Sobrien 192159764Sobrienclass PlatformEvent : public CHeapObj<mtInternal> { 193159764Sobrien private: 194159764Sobrien double CachePad[4]; // increase odds that _mutex is sole occupant of cache line 195159764Sobrien volatile int _Event; 196159764Sobrien volatile int _nParked; 197159764Sobrien pthread_mutex_t _mutex[1]; 198159764Sobrien pthread_cond_t _cond[1]; 199159764Sobrien double PostPad[2]; 200159764Sobrien Thread * _Assoc; 201159764Sobrien 202159764Sobrien public: // TODO-FIXME: make dtor private 203159764Sobrien ~PlatformEvent() { guarantee(0, "invariant"); } 204159764Sobrien 205159764Sobrien public: 206133359Sobrien PlatformEvent() { 207159764Sobrien int status; 208159764Sobrien status = pthread_cond_init (_cond, NULL); 209159764Sobrien assert_status(status == 0, status, "cond_init"); 210159764Sobrien status = pthread_mutex_init (_mutex, NULL); 211234449Sobrien assert_status(status == 0, status, "mutex_init"); 212234449Sobrien _Event = 0; 213234449Sobrien _nParked = 0; 214234449Sobrien _Assoc = NULL; 215234449Sobrien } 216234449Sobrien 217234449Sobrien // Use caution with reset() and fired() -- they may require MEMBARs 218234449Sobrien void reset() { _Event = 0; } 219234449Sobrien int fired() { return _Event; } 220234449Sobrien void park(); 221159764Sobrien void unpark(); 222159764Sobrien int TryPark(); 223159764Sobrien int park(jlong millis); 224159764Sobrien void SetAssociation(Thread * a) { _Assoc = a; } 225159764Sobrien}; 226159764Sobrien 227159764Sobrienclass PlatformParker : public CHeapObj<mtInternal> { 228159764Sobrien protected: 229159764Sobrien pthread_mutex_t _mutex[1]; 230159764Sobrien pthread_cond_t _cond[1]; 231159764Sobrien 232159764Sobrien public: // TODO-FIXME: make dtor private 233159764Sobrien ~PlatformParker() { guarantee(0, "invariant"); } 234159764Sobrien 235159764Sobrien public: 236159764Sobrien PlatformParker() { 237159764Sobrien int status; 238234449Sobrien status = pthread_cond_init (_cond, NULL); 239234449Sobrien assert_status(status == 0, status, "cond_init"); 240234449Sobrien status = pthread_mutex_init (_mutex, NULL); 241234449Sobrien assert_status(status == 0, status, "mutex_init"); 242234449Sobrien } 243234449Sobrien}; 244159764Sobrien 245234449Sobrien#endif // OS_BSD_VM_OS_BSD_HPP 246234449Sobrien