1/*
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2013, 2016 SAP SE. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26#ifndef OS_AIX_VM_OS_AIX_HPP
27#define OS_AIX_VM_OS_AIX_HPP
28
29// Information about the protection of the page at address '0' on this os.
30static bool zero_page_read_protected() { return false; }
31
32// Class Aix defines the interface to the Aix operating systems.
33
34class Aix {
35  friend class os;
36
37  static bool libjsig_is_loaded;        // libjsig that interposes sigaction(),
38                                        // __sigaction(), signal() is loaded
39  static struct sigaction *(*get_signal_action)(int);
40  static struct sigaction *get_preinstalled_handler(int);
41  static void save_preinstalled_handler(int, struct sigaction&);
42
43  static void check_signal_handler(int sig);
44
45 private:
46
47  static julong _physical_memory;
48  static pthread_t _main_thread;
49  static Mutex* _createThread_lock;
50  static int _page_size;
51
52  // -1 = uninitialized, 0 = AIX, 1 = OS/400 (PASE)
53  static int _on_pase;
54
55  // 0 = uninitialized, otherwise 16 bit number:
56  //  lower 8 bit - minor version
57  //  higher 8 bit - major version
58  //  For AIX, e.g. 0x0601 for AIX 6.1
59  //  for OS/400 e.g. 0x0504 for OS/400 V5R4
60  static uint32_t _os_version;
61
62  // -1 = uninitialized,
63  //  0 - SPEC1170 not requested (XPG_SUS_ENV is OFF or not set)
64  //  1 - SPEC1170 requested (XPG_SUS_ENV is ON)
65  static int _xpg_sus_mode;
66
67  // -1 = uninitialized,
68  //  0 - EXTSHM=OFF or not set
69  //  1 - EXTSHM=ON
70  static int _extshm;
71
72  static julong available_memory();
73  static julong physical_memory() { return _physical_memory; }
74  static void initialize_system_info();
75
76  // OS recognitions (PASE/AIX, OS level) call this before calling any
77  // one of Aix::on_pase(), Aix::os_version().
78  static void initialize_os_info();
79
80  // Scan environment for important settings which might effect the
81  // VM. Trace out settings. Warn about invalid settings and/or
82  // correct them.
83  //
84  // Must run after os::Aix::initialue_os_info().
85  static void scan_environment();
86
87  // Initialize libo4 (on PASE) and libperfstat (on AIX). Call this
88  // before relying on functions from either lib, e.g. Aix::get_meminfo().
89  static void initialize_libo4();
90  static void initialize_libperfstat();
91
92 public:
93  static void init_thread_fpu_state();
94  static pthread_t main_thread(void)                                { return _main_thread; }
95  static void set_createThread_lock(Mutex* lk)                      { _createThread_lock = lk; }
96  static Mutex* createThread_lock(void)                             { return _createThread_lock; }
97  static void hotspot_sigmask(Thread* thread);
98
99  // Given an address, returns the size of the page backing that address
100  static size_t query_pagesize(void* p);
101
102  // Return `true' if the calling thread is the primordial thread. The
103  // primordial thread is the thread which contains the main function,
104  // *not* necessarily the thread which initialized the VM by calling
105  // JNI_CreateJavaVM.
106  static bool is_primordial_thread(void);
107
108  static int page_size(void) {
109    assert(_page_size != -1, "not initialized");
110    return _page_size;
111  }
112
113  static address   ucontext_get_pc(const ucontext_t* uc);
114  static intptr_t* ucontext_get_sp(const ucontext_t* uc);
115  static intptr_t* ucontext_get_fp(const ucontext_t* uc);
116  // Set PC into context. Needed for continuation after signal.
117  static void ucontext_set_pc(ucontext_t* uc, address pc);
118
119  static bool get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr);
120
121  // This boolean allows users to forward their own non-matching signals
122  // to JVM_handle_aix_signal, harmlessly.
123  static bool signal_handlers_are_installed;
124
125  static int get_our_sigflags(int);
126  static void set_our_sigflags(int, int);
127  static void signal_sets_init();
128  static void install_signal_handlers();
129  static void set_signal_handler(int, bool);
130  static bool is_sig_ignored(int sig);
131
132  static sigset_t* unblocked_signals();
133  static sigset_t* vm_signals();
134  static sigset_t* allowdebug_blocked_signals();
135
136  // For signal-chaining
137  static struct sigaction *get_chained_signal_action(int sig);
138  static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
139
140  // libpthread version string
141  static void libpthread_init();
142
143  // Return default libc guard size for the specified thread type.
144  static size_t default_guard_size(os::ThreadType thr_type);
145
146  // Function returns true if we run on OS/400 (pase), false if we run
147  // on AIX.
148  static bool on_pase() {
149    assert(_on_pase != -1, "not initialized");
150    return _on_pase ? true : false;
151  }
152
153  // Function returns true if we run on AIX, false if we run on OS/400
154  // (pase).
155  static bool on_aix() {
156    assert(_on_pase != -1, "not initialized");
157    return _on_pase ? false : true;
158  }
159
160  // Get 4 byte AIX kernel version number:
161  // highest 2 bytes: Version, Release
162  // if available: lowest 2 bytes: Tech Level, Service Pack.
163  static uint32_t os_version() {
164    assert(_os_version != 0, "not initialized");
165    return _os_version;
166  }
167
168  // 0 = uninitialized, otherwise 16 bit number:
169  // lower 8 bit - minor version
170  // higher 8 bit - major version
171  // For AIX, e.g. 0x0601 for AIX 6.1
172  // for OS/400 e.g. 0x0504 for OS/400 V5R4
173  static int os_version_short() {
174    return os_version() >> 16;
175  }
176
177  // Convenience method: returns true if running on PASE V5R4 or older.
178  static bool on_pase_V5R4_or_older() {
179    return on_pase() && os_version_short() <= 0x0504;
180  }
181
182  // Convenience method: returns true if running on AIX 5.3 or older.
183  static bool on_aix_53_or_older() {
184    return on_aix() && os_version_short() <= 0x0503;
185  }
186
187  // Returns true if we run in SPEC1170 compliant mode (XPG_SUS_ENV=ON).
188  static bool xpg_sus_mode() {
189    assert(_xpg_sus_mode != -1, "not initialized");
190    return _xpg_sus_mode;
191  }
192
193  // Returns true if EXTSHM=ON.
194  static bool extshm() {
195    assert(_extshm != -1, "not initialized");
196    return _extshm;
197  }
198
199  // result struct for get_meminfo()
200  struct meminfo_t {
201
202    // Amount of virtual memory (in units of 4 KB pages)
203    unsigned long long virt_total;
204
205    // Amount of real memory, in bytes
206    unsigned long long real_total;
207
208    // Amount of free real memory, in bytes
209    unsigned long long real_free;
210
211    // Total amount of paging space, in bytes
212    unsigned long long pgsp_total;
213
214    // Amount of free paging space, in bytes
215    unsigned long long pgsp_free;
216
217  };
218
219  // Functions to retrieve memory information on AIX, PASE.
220  // (on AIX, using libperfstat, on PASE with libo4.so).
221  // Returns true if ok, false if error.
222  static bool get_meminfo(meminfo_t* pmi);
223
224};
225
226
227class PlatformEvent : public CHeapObj<mtInternal> {
228  private:
229    double CachePad [4];   // increase odds that _mutex is sole occupant of cache line
230    volatile int _Event;
231    volatile int _nParked;
232    pthread_mutex_t _mutex  [1];
233    pthread_cond_t  _cond   [1];
234    double PostPad  [2];
235    Thread * _Assoc;
236
237  public:       // TODO-FIXME: make dtor private
238    ~PlatformEvent() { guarantee (0, "invariant"); }
239
240  public:
241    PlatformEvent() {
242      int status;
243      status = pthread_cond_init (_cond, NULL);
244      assert_status(status == 0, status, "cond_init");
245      status = pthread_mutex_init (_mutex, NULL);
246      assert_status(status == 0, status, "mutex_init");
247      _Event   = 0;
248      _nParked = 0;
249      _Assoc   = NULL;
250    }
251
252    // Use caution with reset() and fired() -- they may require MEMBARs
253    void reset() { _Event = 0; }
254    int  fired() { return _Event; }
255    void park ();
256    void unpark ();
257    int  TryPark ();
258    int  park (jlong millis);
259    void SetAssociation (Thread * a) { _Assoc = a; }
260};
261
262class PlatformParker : public CHeapObj<mtInternal> {
263  protected:
264    pthread_mutex_t _mutex [1];
265    pthread_cond_t  _cond  [1];
266
267  public:       // TODO-FIXME: make dtor private
268    ~PlatformParker() { guarantee (0, "invariant"); }
269
270  public:
271    PlatformParker() {
272      int status;
273      status = pthread_cond_init (_cond, NULL);
274      assert_status(status == 0, status, "cond_init");
275      status = pthread_mutex_init (_mutex, NULL);
276      assert_status(status == 0, status, "mutex_init");
277    }
278};
279
280#endif // OS_AIX_VM_OS_AIX_HPP
281