Path: blob/master/src/hotspot/os/posix/os_posix.hpp
40930 views
/*1* Copyright (c) 1999, 2021, 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_POSIX_OS_POSIX_HPP25#define OS_POSIX_OS_POSIX_HPP2627// File conventions28static const char* file_separator() { return "/"; }29static const char* line_separator() { return "\n"; }30static const char* path_separator() { return ":"; }3132class Posix {33friend class os;3435protected:36static void print_distro_info(outputStream* st);37static void print_rlimit_info(outputStream* st);38static void print_uname_info(outputStream* st);39static void print_libversion_info(outputStream* st);40static void print_load_average(outputStream* st);41static void print_uptime_info(outputStream* st);4243// Minimum stack size a thread can be created with (allowing44// the VM to completely create the thread and enter user code).45// The initial values exclude any guard pages (by HotSpot or libc).46// set_minimum_stack_sizes() will add the size required for47// HotSpot guard pages depending on page size and flag settings.48// Libc guard pages are never considered by these values.49static size_t _compiler_thread_min_stack_allowed;50static size_t _java_thread_min_stack_allowed;51static size_t _vm_internal_thread_min_stack_allowed;5253public:54static void init(void); // early initialization - no logging available55static void init_2(void);// later initialization - logging available5657// Return default stack size for the specified thread type58static size_t default_stack_size(os::ThreadType thr_type);59// Check and sets minimum stack sizes60static jint set_minimum_stack_sizes();61static size_t get_initial_stack_size(ThreadType thr_type, size_t req_stack_size);6263// Helper function; describes pthread attributes as short string. String is written64// to buf with len buflen; buf is returned.65static char* describe_pthread_attr(char* buf, size_t buflen, const pthread_attr_t* attr);6667// A safe implementation of realpath which will not cause a buffer overflow if the resolved path68// is longer than PATH_MAX.69// On success, returns 'outbuf', which now contains the path.70// On error, it will return NULL and set errno. The content of 'outbuf' is undefined.71// On truncation error ('outbuf' too small), it will return NULL and set errno to ENAMETOOLONG.72static char* realpath(const char* filename, char* outbuf, size_t outbuflen);7374// Returns true if given uid is root.75static bool is_root(uid_t uid);7677// Returns true if given uid is effective or root uid.78static bool matches_effective_uid_or_root(uid_t uid);7980// Returns true if either given uid is effective uid and given gid is81// effective gid, or if given uid is root.82static bool matches_effective_uid_and_gid_or_root(uid_t uid, gid_t gid);8384static void print_umask(outputStream* st, mode_t umsk);8586static void print_user_info(outputStream* st);8788// Set PC into context. Needed for continuation after signal.89static address ucontext_get_pc(const ucontext_t* ctx);90static void ucontext_set_pc(ucontext_t* ctx, address pc);9192static void to_RTC_abstime(timespec* abstime, int64_t millis);9394static bool handle_stack_overflow(JavaThread* thread, address addr, address pc,95const void* ucVoid,96address* stub);97};9899/*100* Crash protection for the JfrSampler thread. Wrap the callback101* with a sigsetjmp and in case of a SIGSEGV/SIGBUS we siglongjmp102* back.103* To be able to use this - don't take locks, don't rely on destructors,104* don't make OS library calls, don't allocate memory, don't print,105* don't call code that could leave the heap / memory in an inconsistent state,106* or anything else where we are not in control if we suddenly jump out.107*/108class ThreadCrashProtection : public StackObj {109public:110static bool is_crash_protected(Thread* thr) {111return _crash_protection != NULL && _protected_thread == thr;112}113114ThreadCrashProtection();115bool call(os::CrashProtectionCallback& cb);116117static void check_crash_protection(int signal, Thread* thread);118private:119static Thread* _protected_thread;120static ThreadCrashProtection* _crash_protection;121void restore();122sigjmp_buf _jmpbuf;123};124125/*126* This is the platform-specific implementation underpinning127* the ParkEvent class, which itself underpins Java-level monitor128* operations. See park.hpp for details.129* These event objects are type-stable and immortal - we never delete them.130* Events are associated with a thread for the lifetime of the thread.131*/132class PlatformEvent : public CHeapObj<mtSynchronizer> {133private:134double cachePad[4]; // Increase odds that _mutex is sole occupant of cache line135volatile int _event; // Event count/permit: -1, 0 or 1136volatile int _nParked; // Indicates if associated thread is blocked: 0 or 1137pthread_mutex_t _mutex[1]; // Native mutex for locking138pthread_cond_t _cond[1]; // Native condition variable for blocking139double postPad[2];140141protected: // TODO-FIXME: make dtor private142~PlatformEvent() { guarantee(false, "invariant"); } // immortal so can't delete143144public:145PlatformEvent();146void park();147int park(jlong millis);148void unpark();149150// Use caution with reset() and fired() -- they may require MEMBARs151void reset() { _event = 0; }152int fired() { return _event; }153};154155// JSR166 support156// PlatformParker provides the platform dependent base class for the157// Parker class. It basically provides the internal data structures:158// - mutex and convars159// which are then used directly by the Parker methods defined in the OS160// specific implementation files.161// There is significant overlap between the funcionality supported in the162// combination of Parker+PlatformParker and PlatformEvent (above). If Parker163// were more like ObjectMonitor we could use PlatformEvent in both (with some164// API updates of course). But Parker methods use fastpaths that break that165// level of encapsulation - so combining the two remains a future project.166167class PlatformParker {168NONCOPYABLE(PlatformParker);169protected:170enum {171REL_INDEX = 0,172ABS_INDEX = 1173};174volatile int _counter;175int _cur_index; // which cond is in use: -1, 0, 1176pthread_mutex_t _mutex[1];177pthread_cond_t _cond[2]; // one for relative times and one for absolute178179public:180PlatformParker();181~PlatformParker();182};183184// Workaround for a bug in macOSX kernel's pthread support (fixed in Mojave?).185// Avoid ever allocating a pthread_mutex_t at the same address as one of our186// former pthread_cond_t, by using freelists of mutexes and condvars.187// Conditional to avoid extra indirection and padding loss on other platforms.188#ifdef __APPLE__189#define PLATFORM_MONITOR_IMPL_INDIRECT 1190#else191#define PLATFORM_MONITOR_IMPL_INDIRECT 0192#endif193194// Platform specific implementations that underpin VM Mutex/Monitor classes.195// Note that we use "normal" pthread_mutex_t attributes so that recursive196// locking is not supported, which matches the expected semantics of the197// VM Mutex class.198199class PlatformMutex : public CHeapObj<mtSynchronizer> {200#if PLATFORM_MONITOR_IMPL_INDIRECT201class Mutex : public CHeapObj<mtSynchronizer> {202public:203pthread_mutex_t _mutex;204Mutex* _next;205206Mutex();207~Mutex();208};209210Mutex* _impl;211212static pthread_mutex_t _freelist_lock; // used for mutex and cond freelists213static Mutex* _mutex_freelist;214215protected:216class WithFreeListLocked;217pthread_mutex_t* mutex() { return &(_impl->_mutex); }218219public:220PlatformMutex(); // Use freelist allocation of impl.221~PlatformMutex();222223static void init(); // Initialize the freelist.224225#else226227pthread_mutex_t _mutex;228229protected:230pthread_mutex_t* mutex() { return &_mutex; }231232public:233static void init() {} // Nothing needed for the non-indirect case.234235PlatformMutex();236~PlatformMutex();237238#endif // PLATFORM_MONITOR_IMPL_INDIRECT239240private:241NONCOPYABLE(PlatformMutex);242243public:244void lock();245void unlock();246bool try_lock();247};248249class PlatformMonitor : public PlatformMutex {250#if PLATFORM_MONITOR_IMPL_INDIRECT251class Cond : public CHeapObj<mtSynchronizer> {252public:253pthread_cond_t _cond;254Cond* _next;255256Cond();257~Cond();258};259260Cond* _impl;261262static Cond* _cond_freelist;263264pthread_cond_t* cond() { return &(_impl->_cond); }265266public:267PlatformMonitor(); // Use freelist allocation of impl.268~PlatformMonitor();269270#else271272pthread_cond_t _cond;273pthread_cond_t* cond() { return &_cond; }274275public:276PlatformMonitor();277~PlatformMonitor();278279#endif // PLATFORM_MONITOR_IMPL_INDIRECT280281private:282NONCOPYABLE(PlatformMonitor);283284public:285int wait(jlong millis);286void notify();287void notify_all();288};289290#endif // OS_POSIX_OS_POSIX_HPP291292293