Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/os/linux/vm/os_linux.hpp
32285 views
/*1* Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef OS_LINUX_VM_OS_LINUX_HPP25#define OS_LINUX_VM_OS_LINUX_HPP2627// Linux_OS defines the interface to Linux operating systems2829/* pthread_getattr_np comes with LinuxThreads-0.9-7 on RedHat 7.1 */30typedef int (*pthread_getattr_func_type) (pthread_t, pthread_attr_t *);3132// Information about the protection of the page at address '0' on this os.33static bool zero_page_read_protected() { return true; }3435class Linux {36friend class os;37friend class OSContainer;38friend class TestReserveMemorySpecial;3940// For signal-chaining41#define MAXSIGNUM 3242static struct sigaction sigact[MAXSIGNUM]; // saved preinstalled sigactions43static unsigned int sigs; // mask of signals that have44// preinstalled signal handlers45static bool libjsig_is_loaded; // libjsig that interposes sigaction(),46// __sigaction(), signal() is loaded47static struct sigaction *(*get_signal_action)(int);48static struct sigaction *get_preinstalled_handler(int);49static void save_preinstalled_handler(int, struct sigaction&);5051static void check_signal_handler(int sig);5253// For signal flags diagnostics54static int sigflags[MAXSIGNUM];5556static int (*_clock_gettime)(clockid_t, struct timespec *);57static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);58static int (*_pthread_setname_np)(pthread_t, const char*);5960static address _initial_thread_stack_bottom;61static uintptr_t _initial_thread_stack_size;6263static const char *_glibc_version;64static const char *_libpthread_version;6566static bool _is_floating_stack;67static bool _is_NPTL;68static bool _supports_fast_thread_cpu_time;6970static GrowableArray<int>* _cpu_to_node;71static GrowableArray<int>* _nindex_to_node;7273protected:7475static julong _physical_memory;76static pthread_t _main_thread;77static Mutex* _createThread_lock;78static int _page_size;79static const int _vm_default_page_size;8081static julong available_memory();82static julong physical_memory() { return _physical_memory; }83static void set_physical_memory(julong phys_mem) { _physical_memory = phys_mem; }84static int active_processor_count();8586static void initialize_system_info();8788static int commit_memory_impl(char* addr, size_t bytes, bool exec);89static int commit_memory_impl(char* addr, size_t bytes,90size_t alignment_hint, bool exec);9192static void set_glibc_version(const char *s) { _glibc_version = s; }93static void set_libpthread_version(const char *s) { _libpthread_version = s; }9495static bool supports_variable_stack_size();9697static void set_is_NPTL() { _is_NPTL = true; }98static void set_is_LinuxThreads() { _is_NPTL = false; }99static void set_is_floating_stack() { _is_floating_stack = true; }100101static void rebuild_cpu_to_node_map();102static void rebuild_nindex_to_node_map();103static GrowableArray<int>* cpu_to_node() { return _cpu_to_node; }104static GrowableArray<int>* nindex_to_node() { return _nindex_to_node; }105106static size_t find_large_page_size();107static size_t setup_large_page_size();108109static bool setup_large_page_type(size_t page_size);110static bool transparent_huge_pages_sanity_check(bool warn, size_t pages_size);111static bool hugetlbfs_sanity_check(bool warn, size_t page_size);112113static char* reserve_memory_special_shm(size_t bytes, size_t alignment, char* req_addr, bool exec);114static char* reserve_memory_special_huge_tlbfs(size_t bytes, size_t alignment, char* req_addr, bool exec);115static char* reserve_memory_special_huge_tlbfs_only(size_t bytes, char* req_addr, bool exec);116static char* reserve_memory_special_huge_tlbfs_mixed(size_t bytes, size_t alignment, char* req_addr, bool exec);117118static bool release_memory_special_impl(char* base, size_t bytes);119static bool release_memory_special_shm(char* base, size_t bytes);120static bool release_memory_special_huge_tlbfs(char* base, size_t bytes);121122static void print_full_memory_info(outputStream* st);123static void print_container_info(outputStream* st);124static void print_distro_info(outputStream* st);125static void print_libversion_info(outputStream* st);126127public:128static bool _stack_is_executable;129static void *dlopen_helper(const char *name, char *ebuf, int ebuflen);130static void *dll_load_in_vmthread(const char *name, char *ebuf, int ebuflen);131132static void init_thread_fpu_state();133static int get_fpu_control_word();134static void set_fpu_control_word(int fpu_control);135static pthread_t main_thread(void) { return _main_thread; }136// returns kernel thread id (similar to LWP id on Solaris), which can be137// used to access /proc138static pid_t gettid();139static void set_createThread_lock(Mutex* lk) { _createThread_lock = lk; }140static Mutex* createThread_lock(void) { return _createThread_lock; }141static void hotspot_sigmask(Thread* thread);142143static address initial_thread_stack_bottom(void) { return _initial_thread_stack_bottom; }144static uintptr_t initial_thread_stack_size(void) { return _initial_thread_stack_size; }145146static int page_size(void) { return _page_size; }147static void set_page_size(int val) { _page_size = val; }148149static int vm_default_page_size(void) { return _vm_default_page_size; }150151static address ucontext_get_pc(ucontext_t* uc);152static intptr_t* ucontext_get_sp(ucontext_t* uc);153static intptr_t* ucontext_get_fp(ucontext_t* uc);154// Set PC into context. Needed for continuation after signal155static void ucontext_set_pc(ucontext_t* uc, address pc);156157// For Analyzer Forte AsyncGetCallTrace profiling support:158//159// This interface should be declared in os_linux_i486.hpp, but160// that file provides extensions to the os class and not the161// Linux class.162static ExtendedPC fetch_frame_from_ucontext(Thread* thread, ucontext_t* uc,163intptr_t** ret_sp, intptr_t** ret_fp);164165// This boolean allows users to forward their own non-matching signals166// to JVM_handle_linux_signal, harmlessly.167static bool signal_handlers_are_installed;168169static int get_our_sigflags(int);170static void set_our_sigflags(int, int);171static void signal_sets_init();172static void install_signal_handlers();173static void set_signal_handler(int, bool);174static bool is_sig_ignored(int sig);175176static sigset_t* unblocked_signals();177static sigset_t* vm_signals();178static sigset_t* allowdebug_blocked_signals();179180// For signal-chaining181static struct sigaction *get_chained_signal_action(int sig);182static bool chained_handler(int sig, siginfo_t* siginfo, void* context);183184// GNU libc and libpthread version strings185static const char *glibc_version() { return _glibc_version; }186static const char *libpthread_version() { return _libpthread_version; }187188// NPTL or LinuxThreads?189static bool is_LinuxThreads() { return !_is_NPTL; }190static bool is_NPTL() { return _is_NPTL; }191192// NPTL is always floating stack. LinuxThreads could be using floating193// stack or fixed stack.194static bool is_floating_stack() { return _is_floating_stack; }195196static void libpthread_init();197static bool libnuma_init();198static void* libnuma_dlsym(void* handle, const char* name);199// libnuma v2 (libnuma_1.2) symbols200static void* libnuma_v2_dlsym(void* handle, const char* name);201// Minimum stack size a thread can be created with (allowing202// the VM to completely create the thread and enter user code)203static size_t min_stack_allowed;204205// Return default stack size or guard size for the specified thread type206static size_t default_stack_size(os::ThreadType thr_type);207static size_t default_guard_size(os::ThreadType thr_type);208209static void capture_initial_stack(size_t max_size);210211// Stack overflow handling212static bool manually_expand_stack(JavaThread * t, address addr);213static int max_register_window_saves_before_flushing();214215// Real-time clock functions216static void clock_init(void);217218// fast POSIX clocks support219static void fast_thread_clock_init(void);220221static inline bool supports_monotonic_clock() {222return _clock_gettime != NULL;223}224225static int clock_gettime(clockid_t clock_id, struct timespec *tp) {226return _clock_gettime ? _clock_gettime(clock_id, tp) : -1;227}228229static int pthread_getcpuclockid(pthread_t tid, clockid_t *clock_id) {230return _pthread_getcpuclockid ? _pthread_getcpuclockid(tid, clock_id) : -1;231}232233static bool supports_fast_thread_cpu_time() {234return _supports_fast_thread_cpu_time;235}236237static jlong fast_thread_cpu_time(clockid_t clockid);238239// pthread_cond clock suppport240private:241static pthread_condattr_t _condattr[1];242243public:244static pthread_condattr_t* condAttr() { return _condattr; }245246// Stack repair handling247248// none present249250// LinuxThreads work-around for 6292965251static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime);252253private:254static void expand_stack_to(address bottom);255256typedef int (*sched_getcpu_func_t)(void);257typedef int (*numa_node_to_cpus_func_t)(int node, unsigned long *buffer, int bufferlen);258typedef int (*numa_max_node_func_t)(void);259typedef int (*numa_num_configured_nodes_func_t)(void);260typedef int (*numa_available_func_t)(void);261typedef int (*numa_tonode_memory_func_t)(void *start, size_t size, int node);262typedef void (*numa_interleave_memory_func_t)(void *start, size_t size, unsigned long *nodemask);263typedef void (*numa_interleave_memory_v2_func_t)(void *start, size_t size, struct bitmask* mask);264265typedef void (*numa_set_bind_policy_func_t)(int policy);266typedef int (*numa_bitmask_isbitset_func_t)(struct bitmask *bmp, unsigned int n);267typedef int (*numa_distance_func_t)(int node1, int node2);268269static sched_getcpu_func_t _sched_getcpu;270static numa_node_to_cpus_func_t _numa_node_to_cpus;271static numa_max_node_func_t _numa_max_node;272static numa_num_configured_nodes_func_t _numa_num_configured_nodes;273static numa_available_func_t _numa_available;274static numa_tonode_memory_func_t _numa_tonode_memory;275static numa_interleave_memory_func_t _numa_interleave_memory;276static numa_interleave_memory_v2_func_t _numa_interleave_memory_v2;277static numa_set_bind_policy_func_t _numa_set_bind_policy;278static numa_bitmask_isbitset_func_t _numa_bitmask_isbitset;279static numa_distance_func_t _numa_distance;280static unsigned long* _numa_all_nodes;281static struct bitmask* _numa_all_nodes_ptr;282static struct bitmask* _numa_nodes_ptr;283284static void set_sched_getcpu(sched_getcpu_func_t func) { _sched_getcpu = func; }285static void set_numa_node_to_cpus(numa_node_to_cpus_func_t func) { _numa_node_to_cpus = func; }286static void set_numa_max_node(numa_max_node_func_t func) { _numa_max_node = func; }287static void set_numa_num_configured_nodes(numa_num_configured_nodes_func_t func) { _numa_num_configured_nodes = func; }288static void set_numa_available(numa_available_func_t func) { _numa_available = func; }289static void set_numa_tonode_memory(numa_tonode_memory_func_t func) { _numa_tonode_memory = func; }290static void set_numa_interleave_memory(numa_interleave_memory_func_t func) { _numa_interleave_memory = func; }291static void set_numa_interleave_memory_v2(numa_interleave_memory_v2_func_t func) { _numa_interleave_memory_v2 = func; }292static void set_numa_set_bind_policy(numa_set_bind_policy_func_t func) { _numa_set_bind_policy = func; }293static void set_numa_bitmask_isbitset(numa_bitmask_isbitset_func_t func) { _numa_bitmask_isbitset = func; }294static void set_numa_distance(numa_distance_func_t func) { _numa_distance = func; }295static void set_numa_all_nodes(unsigned long* ptr) { _numa_all_nodes = ptr; }296static void set_numa_all_nodes_ptr(struct bitmask **ptr) { _numa_all_nodes_ptr = (ptr == NULL ? NULL : *ptr); }297static void set_numa_nodes_ptr(struct bitmask **ptr) { _numa_nodes_ptr = (ptr == NULL ? NULL : *ptr); }298static int sched_getcpu_syscall(void);299public:300static int sched_getcpu() { return _sched_getcpu != NULL ? _sched_getcpu() : -1; }301static int numa_node_to_cpus(int node, unsigned long *buffer, int bufferlen) {302return _numa_node_to_cpus != NULL ? _numa_node_to_cpus(node, buffer, bufferlen) : -1;303}304static int numa_max_node() { return _numa_max_node != NULL ? _numa_max_node() : -1; }305static int numa_num_configured_nodes() {306return _numa_num_configured_nodes != NULL ? _numa_num_configured_nodes() : -1;307}308static int numa_available() { return _numa_available != NULL ? _numa_available() : -1; }309static int numa_tonode_memory(void *start, size_t size, int node) {310return _numa_tonode_memory != NULL ? _numa_tonode_memory(start, size, node) : -1;311}312static void numa_interleave_memory(void *start, size_t size) {313// Use v2 api if available314if (_numa_interleave_memory_v2 != NULL && _numa_all_nodes_ptr != NULL) {315_numa_interleave_memory_v2(start, size, _numa_all_nodes_ptr);316} else if (_numa_interleave_memory != NULL && _numa_all_nodes != NULL) {317_numa_interleave_memory(start, size, _numa_all_nodes);318}319}320static void numa_set_bind_policy(int policy) {321if (_numa_set_bind_policy != NULL) {322_numa_set_bind_policy(policy);323}324}325static int numa_distance(int node1, int node2) {326return _numa_distance != NULL ? _numa_distance(node1, node2) : -1;327}328static int get_node_by_cpu(int cpu_id);329static int get_existing_num_nodes();330// Check if numa node is configured (non-zero memory node).331static bool isnode_in_configured_nodes(unsigned int n) {332if (_numa_bitmask_isbitset != NULL && _numa_all_nodes_ptr != NULL) {333return _numa_bitmask_isbitset(_numa_all_nodes_ptr, n);334} else335return 0;336}337// Check if numa node exists in the system (including zero memory nodes).338static bool isnode_in_existing_nodes(unsigned int n) {339if (_numa_bitmask_isbitset != NULL && _numa_nodes_ptr != NULL) {340return _numa_bitmask_isbitset(_numa_nodes_ptr, n);341} else if (_numa_bitmask_isbitset != NULL && _numa_all_nodes_ptr != NULL) {342// Not all libnuma API v2 implement numa_nodes_ptr, so it's not possible343// to trust the API version for checking its absence. On the other hand,344// numa_nodes_ptr found in libnuma 2.0.9 and above is the only way to get345// a complete view of all numa nodes in the system, hence numa_nodes_ptr346// is used to handle CPU and nodes on architectures (like PowerPC) where347// there can exist nodes with CPUs but no memory or vice-versa and the348// nodes may be non-contiguous. For most of the architectures, like349// x86_64, numa_node_ptr presents the same node set as found in350// numa_all_nodes_ptr so it's possible to use numa_all_nodes_ptr as a351// substitute.352return _numa_bitmask_isbitset(_numa_all_nodes_ptr, n);353} else354return 0;355}356};357358359class PlatformEvent : public CHeapObj<mtInternal> {360private:361double CachePad [4] ; // increase odds that _mutex is sole occupant of cache line362volatile int _Event ;363volatile int _nParked ;364pthread_mutex_t _mutex [1] ;365pthread_cond_t _cond [1] ;366double PostPad [2] ;367Thread * _Assoc ;368369public: // TODO-FIXME: make dtor private370~PlatformEvent() { guarantee (0, "invariant") ; }371372public:373PlatformEvent() {374int status;375status = pthread_cond_init (_cond, os::Linux::condAttr());376assert_status(status == 0, status, "cond_init");377status = pthread_mutex_init (_mutex, NULL);378assert_status(status == 0, status, "mutex_init");379_Event = 0 ;380_nParked = 0 ;381_Assoc = NULL ;382}383384// Use caution with reset() and fired() -- they may require MEMBARs385void reset() { _Event = 0 ; }386int fired() { return _Event; }387void park () ;388void unpark () ;389int TryPark () ;390int park (jlong millis) ; // relative timed-wait only391void SetAssociation (Thread * a) { _Assoc = a ; }392} ;393394class PlatformParker : public CHeapObj<mtInternal> {395protected:396enum {397REL_INDEX = 0,398ABS_INDEX = 1399};400int _cur_index; // which cond is in use: -1, 0, 1401pthread_mutex_t _mutex [1] ;402pthread_cond_t _cond [2] ; // one for relative times and one for abs.403404public: // TODO-FIXME: make dtor private405~PlatformParker() { guarantee (0, "invariant") ; }406407public:408PlatformParker() {409int status;410status = pthread_cond_init (&_cond[REL_INDEX], os::Linux::condAttr());411assert_status(status == 0, status, "cond_init rel");412status = pthread_cond_init (&_cond[ABS_INDEX], NULL);413assert_status(status == 0, status, "cond_init abs");414status = pthread_mutex_init (_mutex, NULL);415assert_status(status == 0, status, "mutex_init");416_cur_index = -1; // mark as unused417}418};419420#endif // OS_LINUX_VM_OS_LINUX_HPP421422423