os_bsd.hpp revision 7996:3eb61269f421
131567Ssef/*
2204977Simp * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
331899Ssef * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
431899Ssef *
531899Ssef * This code is free software; you can redistribute it and/or modify it
631899Ssef * under the terms of the GNU General Public License version 2 only, as
731899Ssef * published by the Free Software Foundation.
831899Ssef *
931899Ssef * This code is distributed in the hope that it will be useful, but WITHOUT
1031899Ssef * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1131899Ssef * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1231899Ssef * version 2 for more details (a copy is included in the LICENSE file that
1331899Ssef * accompanied this code).
1431899Ssef *
1531899Ssef * You should have received a copy of the GNU General Public License version
1631899Ssef * 2 along with this work; if not, write to the Free Software Foundation,
1731899Ssef * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1831899Ssef *
1931899Ssef * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2031899Ssef * or visit www.oracle.com if you need additional information or have any
2131899Ssef * questions.
2231899Ssef *
2331899Ssef */
2431899Ssef
2531899Ssef#ifndef OS_BSD_VM_OS_BSD_HPP
2631899Ssef#define OS_BSD_VM_OS_BSD_HPP
2731899Ssef
2831899Ssef// Bsd_OS defines the interface to Bsd operating systems
2931899Ssef
3031899Ssef// Information about the protection of the page at address '0' on this os.
3131899Ssefstatic bool zero_page_read_protected() { return true; }
3232275Scharnier
3332275Scharnier// pthread_getattr_np comes with BsdThreads-0.9-7 on RedHat 7.1
3450477Spetertypedef int (*pthread_getattr_func_type)(pthread_t, pthread_attr_t *);
3532275Scharnier
3632275Scharnier#ifdef __APPLE__
3731899Ssef// Mac OS X doesn't support clock_gettime. Stub out the type, it is
3831567Ssef// unused
3931567Sseftypedef int clockid_t;
4031567Ssef#endif
4131567Ssef
42127328Salfredclass Bsd {
4385292Sdes  friend class os;
44168569Sdelphij
4585292Sdes  // For signal-chaining
46104581Smike#define MAXSIGNUM 32
4785292Sdes  static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions
4885292Sdes  static unsigned int sigs;             // mask of signals that have
4985292Sdes                                        // preinstalled signal handlers
50158630Spav  static bool libjsig_is_loaded;        // libjsig that interposes sigaction(),
51158630Spav                                        // __sigaction(), signal() is loaded
52158630Spav  static struct sigaction *(*get_signal_action)(int);
53158630Spav  static struct sigaction *get_preinstalled_handler(int);
54158630Spav  static void save_preinstalled_handler(int, struct sigaction&);
55158630Spav
56158630Spav  static void check_signal_handler(int sig);
5785292Sdes
5886138Sgreen  // For signal flags diagnostics
5932275Scharnier  static int sigflags[MAXSIGNUM];
60127328Salfred
61127332Sdwmalone#ifdef __APPLE__
6285292Sdes  // mach_absolute_time
63127332Sdwmalone  static mach_timebase_info_data_t _timebase_info;
6431567Ssef  static volatile uint64_t         _max_abstime;
6531567Ssef#else
6631567Ssef  static int (*_clock_gettime)(clockid_t, struct timespec *);
67101423Smdodd#endif
6831567Ssef
69158630Spav  static GrowableArray<int>* _cpu_to_node;
7085292Sdes
71101282Smdodd protected:
7287703Smarkm
7331567Ssef  static julong _physical_memory;
7431567Ssef  static pthread_t _main_thread;
75171646Smarcel  static int _page_size;
76171646Smarcel
77171646Smarcel  static julong available_memory();
78171646Smarcel  static julong physical_memory() { return _physical_memory; }
79171646Smarcel  static void initialize_system_info();
80171646Smarcel
81171646Smarcel  static bool supports_variable_stack_size();
82171646Smarcel
83171646Smarcel  static void rebuild_cpu_to_node_map();
84171646Smarcel  static GrowableArray<int>* cpu_to_node()    { return _cpu_to_node; }
85171646Smarcel
86171646Smarcel  static bool hugetlbfs_sanity_check(bool warn, size_t page_size);
87171646Smarcel
88171646Smarcel public:
8931567Ssef
90158630Spav  static void init_thread_fpu_state();
9131567Ssef  static pthread_t main_thread(void)                                { return _main_thread; }
92228396Sed
93192025Sdds  static void hotspot_sigmask(Thread* thread);
94192025Sdds
95200751Sjh  static bool is_initial_thread(void);
96200751Sjh  static pid_t gettid();
97200751Sjh
98200751Sjh  static int page_size(void)                                        { return _page_size; }
99200751Sjh  static void set_page_size(int val)                                { _page_size = val; }
100200751Sjh
101200751Sjh  static address   ucontext_get_pc(ucontext_t* uc);
102200751Sjh  static void ucontext_set_pc(ucontext_t* uc, address pc);
103200751Sjh  static intptr_t* ucontext_get_sp(ucontext_t* uc);
104200751Sjh  static intptr_t* ucontext_get_fp(ucontext_t* uc);
105200751Sjh
106200751Sjh  // For Analyzer Forte AsyncGetCallTrace profiling support:
107192025Sdds  //
108192025Sdds  // This interface should be declared in os_bsd_i486.hpp, but
109192025Sdds  // that file provides extensions to the os class and not the
110192025Sdds  // Bsd class.
111192025Sdds  static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc,
112192025Sdds                                              intptr_t** ret_sp, intptr_t** ret_fp);
113192025Sdds
114192025Sdds  // This boolean allows users to forward their own non-matching signals
115192025Sdds  // to JVM_handle_bsd_signal, harmlessly.
116192025Sdds  static bool signal_handlers_are_installed;
117192025Sdds
118192025Sdds  static int get_our_sigflags(int);
119192025Sdds  static void set_our_sigflags(int, int);
120192025Sdds  static void signal_sets_init();
121192025Sdds  static void install_signal_handlers();
122192025Sdds  static void set_signal_handler(int, bool);
123192025Sdds  static bool is_sig_ignored(int sig);
124192025Sdds
125192025Sdds  static sigset_t* unblocked_signals();
126192025Sdds  static sigset_t* vm_signals();
127192025Sdds  static sigset_t* allowdebug_blocked_signals();
128192025Sdds
129192025Sdds  // For signal-chaining
130192025Sdds  static struct sigaction *get_chained_signal_action(int sig);
131192025Sdds  static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
132192025Sdds
133192025Sdds  // Minimum stack size a thread can be created with (allowing
134192025Sdds  // the VM to completely create the thread and enter user code)
135192025Sdds  static size_t min_stack_allowed;
136192025Sdds
137192025Sdds  // Return default stack size or guard size for the specified thread type
138192025Sdds  static size_t default_stack_size(os::ThreadType thr_type);
139192025Sdds  static size_t default_guard_size(os::ThreadType thr_type);
140192025Sdds
141192025Sdds  // Real-time clock functions
142192025Sdds  static void clock_init(void);
143192025Sdds
144192025Sdds  // Stack repair handling
145192025Sdds
146192025Sdds  // none present
147192025Sdds
148192025Sdds  // BsdThreads work-around for 6292965
149192025Sdds  static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);
150192025Sdds
151192025Sdds private:
152192025Sdds  typedef int (*sched_getcpu_func_t)(void);
153192025Sdds  typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);
154192025Sdds  typedef int (*numa_max_node_func_t)(void);
155192025Sdds  typedef int (*numa_available_func_t)(void);
156192025Sdds  typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node);
157192025Sdds  typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask);
158192025Sdds
159192025Sdds  static sched_getcpu_func_t _sched_getcpu;
160192025Sdds  static numa_node_to_cpus_func_t _numa_node_to_cpus;
161192025Sdds  static numa_max_node_func_t _numa_max_node;
162192025Sdds  static numa_available_func_t _numa_available;
163192025Sdds  static numa_tonode_memory_func_t _numa_tonode_memory;
164192025Sdds  static numa_interleave_memory_func_t _numa_interleave_memory;
165192025Sdds  static unsigned long* _numa_all_nodes;
166192025Sdds
167192025Sdds  static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; }
168192025Sdds  static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; }
169192025Sdds  static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; }
170192025Sdds  static void set_numa_available(numa_available_func_t func) { _numa_available = func; }
171192025Sdds  static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; }
172192025Sdds  static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; }
173192025Sdds  static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; }
174192025Sdds public:
175192025Sdds  static int sched_getcpu()  { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }
176192025Sdds  static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {
177192025Sdds    return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1;
178192025Sdds  }
179192025Sdds  static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; }
180192025Sdds  static int numa_available() { return _numa_available != NULL ? _numa_available() : -1; }
181192025Sdds  static int numa_tonode_memory(void *start, size_t size, int node) {
182192025Sdds    return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1;
183192025Sdds  }
184192025Sdds  static void numa_interleave_memory(void *start, size_t size) {
185192025Sdds    if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) {
186192025Sdds      _numa_interleave_memory(start, size, _numa_all_nodes);
187192025Sdds    }
188192025Sdds  }
189192025Sdds  static int get_node_by_cpu(int cpu_id);
190192025Sdds};
191192025Sdds
192192025Sdds
193192025Sddsclass PlatformEvent : public CHeapObj<mtInternal> {
194192025Sdds private:
195192025Sdds  double CachePad[4];   // increase odds that _mutex is sole occupant of cache line
196192025Sdds  volatile int _Event;
197192025Sdds  volatile int _nParked;
198192025Sdds  pthread_mutex_t _mutex[1];
199192025Sdds  pthread_cond_t  _cond[1];
200192025Sdds  double PostPad[2];
201192025Sdds  Thread * _Assoc;
202192025Sdds
203192025Sdds public:       // TODO-FIXME: make dtor private
204192025Sdds  ~PlatformEvent() { guarantee(0, "invariant"); }
205192025Sdds
206192025Sdds public:
207192025Sdds  PlatformEvent() {
208192025Sdds    int status;
209192025Sdds    status = pthread_cond_init(_cond, NULL);
210192025Sdds    assert_status(status == 0, status, "cond_init");
211192025Sdds    status = pthread_mutex_init(_mutex, NULL);
212192025Sdds    assert_status(status == 0, status, "mutex_init");
213192025Sdds    _Event   = 0;
214192025Sdds    _nParked = 0;
215192025Sdds    _Assoc   = NULL;
216192025Sdds  }
217192025Sdds
218192025Sdds  // Use caution with reset() and fired() -- they may require MEMBARs
219192025Sdds  void reset() { _Event = 0; }
220192025Sdds  int  fired() { return _Event; }
221192025Sdds  void park();
222192025Sdds  void unpark();
223192025Sdds  int  park(jlong millis);
224192025Sdds  void SetAssociation(Thread * a) { _Assoc = a; }
225192025Sdds};
226192025Sdds
227192025Sddsclass PlatformParker : public CHeapObj<mtInternal> {
228192025Sdds protected:
229192025Sdds  pthread_mutex_t _mutex[1];
230192025Sdds  pthread_cond_t  _cond[1];
231192025Sdds
232192025Sdds public:       // TODO-FIXME: make dtor private
233192025Sdds  ~PlatformParker() { guarantee(0, "invariant"); }
234192025Sdds
235192025Sdds public:
236192025Sdds  PlatformParker() {
237192025Sdds    int status;
238192025Sdds    status = pthread_cond_init(_cond, NULL);
239192025Sdds    assert_status(status == 0, status, "cond_init");
240192025Sdds    status = pthread_mutex_init(_mutex, NULL);
241192025Sdds    assert_status(status == 0, status, "mutex_init");
242192025Sdds  }
243192025Sdds};
244192025Sdds
245200780Sjh#endif // OS_BSD_VM_OS_BSD_HPP
246200780Sjh