/* * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
// Rules for using and implementing methods declared in the "os" class // =================================================================== // // The "os" class defines a number of the interfaces for porting HotSpot // to different operating systems. For example, I/O, memory, timing, etc. // Note that additional classes such as Semaphore, Mutex, etc., are used for // porting specific groups of features. // // Structure of os*.{cpp, hpp} files // // - os.hpp // // (This file) declares the entire API of the "os" class. // // - os.inline.hpp // // To use any of the inline methods declared in the "os" class, this // header file must be included. // // - src/hotspot/os/<os>/os_<os>.hpp // - src/hotspot/os/posix/os_posix.hpp // // These headers declare APIs that should be used only within the // platform-specific source files for that particular OS. // // For example, os_linux.hpp declares the os::Linux class, which provides // many methods that can be used by files under os/linux/ and os_cpu/linux_*/ // // os_posix.hpp can be used by platform-specific files for POSIX-like // OSes such as aix, bsd and linux. // // Platform-independent source files should not include these header files // (although sadly there are some rare exceptions ...) // // - os.cpp // // Platform-independent methods of the "os" class are defined // in os.cpp. These are not part of the porting interface, but rather // can be considered as convenience functions for accessing // the porting interface. E.g., os::print_function_and_library_name(). // // The methods declared in os.hpp but not implemented in os.cpp are // a part the HotSpot Porting APIs. They must be implemented in one of // the following four files: // // - src/hotspot/os/<os>/os_<os>.inline.hpp // - src/hotspot/os_cpu/<os>_<cpu>/os_<os>_<cpu>.inline.hpp // - src/hotspot/os/<os>/os_<os>.cpp // - src/hotspot/os_cpu/<os>_<cpu>/os_<os>_<cpu>.cpp // // The Porting APIs declared as "inline" in os.hpp MUST be // implemented in one of the two .inline.hpp files, depending on // whether the feature is specific to a particular CPU architecture // for this OS. These two files are automatically included by // os.inline.hpp. Platform-independent source files must not include // these two files directly. // // If the full definition of an inline method is too complex to fit in a // header file, the actual implementation can be deferred to another // method defined in the .cpp files. // // The Porting APIs that are *not* declared as "inline" in os.hpp MUST // be implemented in one of the two .cpp files above. These files // also implement OS-specific APIs such as os::Linux, os::Posix, etc. // // (Note: on the POSIX-like platforms, some of the Porting APIs are implemented // in os_posix.cpp instead).
class Thread; class JavaThread; class NativeCallStack; class methodHandle; class OSThread; class Mutex;
struct jvmtiTimerInfo;
template<class E> class GrowableArray;
// %%%%% Moved ThreadState, START_FN, OSThread to new osThread.hpp. -- Rose
// Platform-independent error return values from OS functions enum OSReturn {
OS_OK = 0, // Operation was successful
OS_ERR = -1, // Operation failed
OS_INTRPT = -2, // Operation was interrupted
OS_TIMEOUT = -3, // Operation timed out
OS_NOMEM = -5, // Operation failed for lack of memory
OS_NORESOURCE = -6 // Operation failed for lack of nonmemory resource
};
enum ThreadPriority { // JLS 20.20.1-3
NoPriority = -1, // Initial non-priority value
MinPriority = 1, // Minimum priority
NormPriority = 5, // Normal (non-daemon) priority
NearMaxPriority = 9, // High priority, used for VMThread
MaxPriority = 10, // Highest priority, used for WatcherThread // ensures that VMThread doesn't starve profiler
CriticalPriority = 11 // Critical thread priority
};
enum WXMode {
WXWrite,
WXExec
};
// Executable parameter flag for os::commit_memory() and // os::commit_memory_or_exit(). constbool ExecMem = true;
// Typedef for structured exception handling support typedefvoid (*java_call_t)(JavaValue* value, const methodHandle& method, JavaCallArguments* args, JavaThread* thread);
class MallocTracker;
class os: AllStatic { friendclass VMStructs; friendclass JVMCIVMStructs; friendclass MallocTracker;
// A simple value class holding a set of page sizes (similar to sigset_t) class PageSizes {
size_t _v; // actually a bitmap. public:
PageSizes() : _v(0) {} void add(size_t pagesize); bool contains(size_t pagesize) const; // Given a page size, return the next smaller page size in this set, or 0.
size_t next_smaller(size_t pagesize) const; // Given a page size, return the next larger page size in this set, or 0.
size_t next_larger(size_t pagesize) const; // Returns the largest page size in this set, or 0 if set is empty.
size_t largest() const; // Returns the smallest page size in this set, or 0 if set is empty.
size_t smallest() const; // Prints one line of comma separated, human readable page sizes, "empty" if empty. void print_on(outputStream* st) const;
};
// Get summary strings for system information in buffer provided staticvoid get_summary_cpu_info(char* buf, size_t buflen); staticvoid get_summary_os_info(char* buf, size_t buflen);
public: staticvoid init(void); // Called before command line parsing
staticvoid init_container_support() { // Called during command line parsing.
LINUX_ONLY(pd_init_container_support();)
}
staticvoid init_before_ergo(void); // Called after command line parsing // before VM ergonomics processing. static jint init_2(void); // Called after command line parsing // and VM ergonomics processing
// Get environ pointer, platform independently staticchar** get_environ();
// Returns the elapsed time in seconds since the vm started. staticdouble elapsedTime();
// Returns real time in seconds since an arbitrary point // in the past. staticbool getTimesSecs(double* process_real_time, double* process_user_time, double* process_system_time);
// Interface to the performance counter static jlong elapsed_counter(); static jlong elapsed_frequency();
// The "virtual time" of a thread is the amount of time a thread has // actually run. The first function indicates whether the OS supports // this functionality for the current thread, and if so the second // returns the elapsed virtual time for the current thread. staticbool supports_vtime(); staticdouble elapsedVTime();
// Return current local time in a string (YYYY-MM-DD HH:MM:SS). // It is MT safe, but not async-safe, as reading time zone // information may require a lock on some platforms. staticchar* local_time_string(char *buf, size_t buflen); staticstruct tm* localtime_pd (const time_t* clock, struct tm* res); staticstruct tm* gmtime_pd (const time_t* clock, struct tm* res);
// "YYYY-MM-DDThh:mm:ss.mmm+zzzz" incl. terminating zero staticconst size_t iso8601_timestamp_size = 29;
// Fill in buffer with an ISO-8601 string corresponding to the given javaTimeMillis value // E.g., YYYY-MM-DDThh:mm:ss.mmm+zzzz. // Returns buffer, or NULL if it failed. staticchar* iso8601_time(jlong milliseconds_since_19700101, char* buffer,
size_t buffer_length, bool utc = false);
// Fill in buffer with current local time as an ISO-8601 string. // E.g., YYYY-MM-DDThh:mm:ss.mmm+zzzz. // Returns buffer, or NULL if it failed. staticchar* iso8601_time(char* buffer, size_t buffer_length, bool utc = false);
// Interface for detecting multiprocessor system staticinlinebool is_MP() { // During bootstrap if _processor_count is not yet initialized // we claim to be MP as that is safest. If any platform has a // stub generator that might be triggered in this phase and for // which being declared MP when in fact not, is a problem - then // the bootstrap routine for the stub generator needs to check // the processor count directly and leave the bootstrap routine // in place until called after initialization has occurred. return (_processor_count != 1);
}
// Returns the id of the processor on which the calling thread is currently executing. // The returned value is guaranteed to be between 0 and (os::processor_count() - 1). static uint processor_id();
// number of CPUs staticint processor_count() { return _processor_count;
} staticvoid set_processor_count(int count) { _processor_count = count; }
// Returns the number of CPUs this process is currently allowed to run on. // Note that on some OSes this can change dynamically. staticint active_processor_count();
// At startup the number of active CPUs this process is allowed to run on. // This value does not change dynamically. May be different from active_processor_count(). staticint initial_active_processor_count() {
assert(_initial_active_processor_count > 0, "Initial active processor count not set yet."); return _initial_active_processor_count;
}
// Give a name to the current thread. staticvoid set_native_thread_name(constchar *name);
// Interface for stack banging (predetect possible stack overflow for // exception processing) There are guard pages, and above that shadow // pages for stack overflow checking. inlinestaticbool uses_stack_guard_pages(); inlinestaticbool must_commit_stack_guard_pages(); inlinestaticvoid map_stack_shadow_pages(address sp); staticbool stack_shadow_pages_available(Thread *thread, const methodHandle& method, address sp);
private: // Minimum stack size a thread can be created with (allowing // the VM to completely create the thread and enter user code). // The initial values exclude any guard pages (by HotSpot or libc). // set_minimum_stack_sizes() will add the size required for // HotSpot guard pages depending on page size and flag settings. // Libc guard pages are never considered by these values. static size_t _compiler_thread_min_stack_allowed; static size_t _java_thread_min_stack_allowed; static size_t _vm_internal_thread_min_stack_allowed; static size_t _os_min_stack_allowed;
// Check and sets minimum stack sizes static jint set_minimum_stack_sizes();
public: // Find committed memory region within specified range (start, start + size), // return true if found any staticbool committed_in_range(address start, size_t size, address& committed_start, size_t& committed_size);
// The set of page sizes which the VM is allowed to use (may be a subset of // the page sizes actually available on the platform). staticconst PageSizes& page_sizes() { return _page_sizes; }
// Returns the page size to use for a region of memory. // region_size / min_pages will always be greater than or equal to the // returned value. The returned value will divide region_size. static size_t page_size_for_region_aligned(size_t region_size, size_t min_pages);
// Returns the page size to use for a region of memory. // region_size / min_pages will always be greater than or equal to the // returned value. The returned value might not divide region_size. static size_t page_size_for_region_unaligned(size_t region_size, size_t min_pages);
// Return the largest page size that can be used static size_t max_page_size() { return page_sizes().largest(); }
// Return a lower bound for page sizes. Also works before os::init completed. static size_t min_page_size() { return 4 * K; }
// Methods for tracing page sizes returned by the above method. // The region_{min,max}_size parameters should be the values // passed to page_size_for_region() and page_size should be the result of that // call. The (optional) base and size parameters should come from the // ReservedSpace base() and size() methods. staticvoid trace_page_sizes(constchar* str, const size_t* page_sizes, int count); staticvoid trace_page_sizes(constchar* str, const size_t region_min_size, const size_t region_max_size, const size_t page_size, constchar* base, const size_t size); staticvoid trace_page_sizes_for_requested_size(constchar* str, const size_t requested_size, const size_t page_size, const size_t alignment, constchar* base, const size_t size);
// Reserves virtual memory that starts at an address that is aligned to 'alignment'. staticchar* reserve_memory_aligned(size_t size, size_t alignment, bool executable = false);
// Attempts to reserve the virtual memory at [addr, addr + bytes). // Does not overwrite existing mappings. staticchar* attempt_reserve_memory_at(char* addr, size_t bytes, bool executable = false);
staticbool commit_memory(char* addr, size_t bytes, bool executable); staticbool commit_memory(char* addr, size_t size, size_t alignment_hint, bool executable); // Same as commit_memory() that either succeeds or calls // vm_exit_out_of_memory() with the specified mesg. staticvoid commit_memory_or_exit(char* addr, size_t bytes, bool executable, constchar* mesg); staticvoid commit_memory_or_exit(char* addr, size_t size,
size_t alignment_hint, bool executable, constchar* mesg); staticbool uncommit_memory(char* addr, size_t bytes, bool executable = false); staticbool release_memory(char* addr, size_t bytes);
// Does the platform support trimming the native heap? staticbool can_trim_native_heap();
// Trim the C-heap. Optionally returns working set size change (RSS+Swap) in *rss_change. // Note: If trimming succeeded but no size change information could be obtained, // rss_change.after will contain SIZE_MAX upon return. struct size_change_t { size_t before; size_t after; }; staticbool trim_native_heap(size_change_t* rss_change = nullptr);
// A diagnostic function to print memory mappings in the given range. staticvoid print_memory_mappings(char* addr, size_t bytes, outputStream* st); // Prints all mappings staticvoid print_memory_mappings(outputStream* st);
// Touch memory pages that cover the memory range from start to end // (exclusive) to make the OS back the memory range with actual memory. // Other threads may use the memory range concurrently with pretouch. staticvoid pretouch_memory(void* start, void* end, size_t page_size = vm_page_size());
staticbool guard_memory(char* addr, size_t bytes); staticbool unguard_memory(char* addr, size_t bytes); staticbool create_stack_guard_pages(char* addr, size_t bytes); staticbool pd_create_stack_guard_pages(char* addr, size_t bytes); staticbool remove_stack_guard_pages(char* addr, size_t bytes); // Helper function to create a new file with template jvmheap.XXXXXX. // Returns a valid fd on success or else returns -1 staticint create_file_for_heap(constchar* dir); // Map memory to the file referred by fd. This function is slightly different from map_memory() // and is added to be used for implementation of -XX:AllocateHeapAt staticchar* map_memory_to_file(size_t size, int fd); staticchar* map_memory_to_file_aligned(size_t size, size_t alignment, int fd); staticchar* map_memory_to_file(char* base, size_t size, int fd); staticchar* attempt_map_memory_to_file_at(char* base, size_t size, int fd); // Replace existing reserved memory with file mapping staticchar* replace_existing_mapping_with_file_mapping(char* base, size_t size, int fd);
// The "main thread", also known as "starting thread", is the thread // that loads/creates the JVM via JNI_CreateJavaVM. staticbool create_main_thread(JavaThread* thread);
// The primordial thread is the initial process thread. The java // launcher never uses the primordial thread as the main thread, but // applications that host the JVM directly may do so. Some platforms // need special-case handling of the primordial thread if it attaches // to the VM. staticbool is_primordial_thread(void) #ifdefined(_WINDOWS) || defined(BSD) // No way to identify the primordial thread.
{ returnfalse; } #else
; #endif
// Returns true if successful. staticbool signal_thread(Thread* thread, int sig, constchar* reason);
staticvoid free_thread(OSThread* osthread);
// thread id on Linux/64bit is 64bit, on Windows it's 32bit static intx current_thread_id(); staticint current_process_id();
// Short standalone OS sleep routines suitable for slow path spin loop. // Ignores safepoints/suspension/Thread.interrupt() (so keep it short). // ms/ns = 0, will sleep for the least amount of time allowed by the OS. // Maximum sleep time is just under 1 second. staticvoid naked_short_sleep(jlong ms); staticvoid naked_short_nanosleep(jlong ns); // Longer standalone OS sleep routine - a convenience wrapper around // multiple calls to naked_short_sleep. Only for use by non-JavaThreads. staticvoid naked_sleep(jlong millis); // Never returns, use with CAUTION staticvoid infinite_sleep(); staticvoid naked_yield () ; static OSReturn set_priority(Thread* thread, ThreadPriority priority); static OSReturn get_priority(const Thread* const thread, ThreadPriority& priority);
// run cmd in a separate process and return its exit code; or -1 on failures. // Note: only safe to use in fatal error situations. staticint fork_and_exec(constchar *cmd);
// Call ::exit() on all platforms staticvoidexit(int num);
// Call ::_exit() on all platforms. Similar semantics to die() except we never // want a core dump. staticvoid _exit(int num);
// Terminate the VM, but don't exit the process staticvoid shutdown();
// Terminate with an error. Default is to generate a core file on platforms // that support such things. This calls shutdown() and then aborts. staticvoid abort(bool dump_core, void *siginfo, constvoid *context); staticvoid abort(bool dump_core = true);
// Die immediately, no exit hook, no abort hook, no cleanup. // Dump a core file, if possible, for debugging. os::abort() is the // preferred means to abort the VM on error. os::die() should only // be called if something has gone badly wrong. CreateCoredumpOnCrash // is intentionally not honored by this function. staticvoid die();
// File i/o operations staticint open(constchar *path, int oflag, int mode); static FILE* fdopen(int fd, constchar* mode); static FILE* fopen(constchar* path, constchar* mode); static jlong lseek(int fd, jlong offset, int whence); staticbool file_exists(constchar* file); // This function, on Windows, canonicalizes a given path (see os_windows.cpp for details). // On Posix, this function is a noop: it does not change anything and just returns // the input pointer. staticchar* native_path(char *path); staticint ftruncate(int fd, jlong length); staticint get_fileno(FILE* fp); staticvoid flockfile(FILE* fp); staticvoid funlockfile(FILE* fp);
// Builds the platform-specific name of a library. // Returns false if the buffer is too small. staticbool dll_build_name(char* buffer, size_t size, constchar* fname);
// Builds a platform-specific full library path given an ld path and // unadorned library name. Returns true if the buffer contains a full // path to an existing file, false otherwise. If pathname is empty, // uses the path to the current directory. staticbool dll_locate_lib(char* buffer, size_t size, constchar* pathname, constchar* fname);
// Symbol lookup, find nearest function name; basically it implements // dladdr() for all platforms. Name of the nearest function is copied // to buf. Distance from its base address is optionally returned as offset. // If function name is not found, buf[0] is set to '\0' and offset is // set to -1 (if offset is non-NULL). staticbool dll_address_to_function_name(address addr, char* buf, int buflen, int* offset, bool demangle = true);
// Locate DLL/DSO. On success, full path of the library is copied to // buf, and offset is optionally set to be the distance between addr // and the library's base address. On failure, buf[0] is set to '\0' // and offset is set to -1 (if offset is non-NULL). staticbool dll_address_to_library_name(address addr, char* buf, int buflen, int* offset);
// Given an address, attempt to locate both the symbol and the library it // resides in. If at least one of these steps was successful, prints information // and returns true. // - if no scratch buffer is given, stack is used // - shorten_paths: path is omitted from library name // - demangle: function name is demangled // - strip_arguments: arguments are stripped (requires demangle=true) // On success prints either one of: // "<function name>+<offset> in <library>" // "<function name>+<offset>" // "<address> in <library>+<offset>" staticbool print_function_and_library_name(outputStream* st,
address addr, char* buf = NULL, int buflen = 0, bool shorten_paths = true, bool demangle = true, bool strip_arguments = false);
// Used only on PPC. inlinestaticvoid* resolve_function_descriptor(void* p);
// Find out whether the pc is in the static code for jvm.dll/libjvm.so. staticbool address_is_in_vm(address addr);
// Loads .dll/.so and // in case of error it checks if .dll/.so was built for the // same architecture as HotSpot is running on // in case of an error NULL is returned and an error message is stored in ebuf staticvoid* dll_load(constchar *name, char *ebuf, int ebuflen);
// lookup symbol in a shared library staticvoid* dll_lookup(void* handle, constchar* name);
// Replacement for strerror(). // Will return the english description of the error (e.g. "File not found", as // suggested in the POSIX standard. // Will return "Unknown error" for an unknown errno value. // Will not attempt to localize the returned string. // Will always return a valid string which is a static constant. // Will not change the value of errno. staticconstchar* strerror(int e);
// Will return the literalized version of the given errno (e.g. "EINVAL" // for EINVAL). // Will return "Unknown error" for an unknown errno value. // Will always return a valid string which is a static constant. // Will not change the value of errno. staticconstchar* errno_name(int e);
// wait for a key press if PauseAtExit is set staticvoid wait_for_keypress_at_exit(void);
// The following two functions are used by fatal error handler to trace // native (C) frames. They are not part of frame.hpp/frame.cpp because // frame.hpp/cpp assume thread is JavaThread, and also because different // OS/compiler may have different convention or provide different API to // walk C frames. // // We don't attempt to become a debugger, so we only follow frames if that // does not require a lookup in the unwind table, which is part of the binary // file but may be unsafe to read after a fatal error. So on x86, we can // only walk stack if %ebp is used as frame pointer; on ia64, it's not // possible to walk C stack without having the unwind table. staticbool is_first_C_frame(frame *fr); static frame get_sender_for_C_frame(frame *fr);
// return current frame. pc() and sp() are set to NULL on failure. static frame current_frame();
staticvoid print_hex_dump(outputStream* st, address start, address end, int unitsize, int bytes_per_line, address logical_start); staticvoid print_hex_dump(outputStream* st, address start, address end, int unitsize) {
print_hex_dump(st, start, end, unitsize, /*bytes_per_line=*/16, /*logical_start=*/start);
}
// returns a string to describe the exception/signal; // returns NULL if exception_code is not an OS exception/signal. staticconstchar* exception_name(int exception_code, char* buf, size_t buflen);
// Returns the signal number (e.g. 11) for a given signal name (SIGSEGV). staticint get_signal_number(constchar* signal_name);
// Returns native Java library, loads if necessary staticvoid* native_java_library();
// Fills in path to jvm.dll/libjvm.so (used by the Disassembler) staticvoid jvm_path(char *buf, jint buflen);
// JNI names staticvoid print_jni_name_prefix_on(outputStream* st, int args_size); staticvoid print_jni_name_suffix_on(outputStream* st, int args_size);
// Init os specific system properties values staticvoid init_system_properties_values();
// Retrieve native stack frames. // Parameter: // stack: an array to storage stack pointers. // frames: size of above array. // toSkip: number of stack frames to skip at the beginning. // Return: number of stack frames captured. staticint get_native_stack(address* stack, int size, int toSkip = 0);
// Support for signals staticvoid initialize_jdk_signal_support(TRAPS); staticvoid signal_notify(int signal_number); staticint signal_wait(); staticvoid terminate_signal_thread(); staticint sigexitnum_pd();
// random number generation staticint random(); // return 32bit pseudorandom number staticint next_random(unsignedint rand_seed); // pure version of random() staticvoid init_random(unsignedint initval); // initialize random sequence
// Structured OS Exception support staticvoid os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method, JavaCallArguments* args, JavaThread* thread);
// On Posix compatible OS it will simply check core dump limits while on Windows // it will check if dump file can be created. Check or prepare a core dump to be // taken at a later point in the same thread in os::abort(). Use the caller // provided buffer as a scratch buffer. The status message which will be written // into the error log either is file location or a short error message, depending // on the checking result. staticvoid check_dump_limit(char* buffer, size_t bufferSize);
// Get the default path to the core file // Returns the length of the string staticint get_core_path(char* buffer, size_t bufferSize);
// JVMTI & JVM monitoring and management support // The thread_cpu_time() and current_thread_cpu_time() are only // supported if is_thread_cpu_time_supported() returns true.
// Thread CPU Time - return the fast estimate on a platform // On Linux - fast clock_gettime where available - user+sys // - otherwise: very slow /proc fs - user+sys // On Windows - GetThreadTimes - user+sys static jlong current_thread_cpu_time(); static jlong thread_cpu_time(Thread* t);
// Thread CPU Time with user_sys_cpu_time parameter. // // If user_sys_cpu_time is true, user+sys time is returned. // Otherwise, only user time is returned static jlong current_thread_cpu_time(bool user_sys_cpu_time); static jlong thread_cpu_time(Thread* t, bool user_sys_cpu_time);
// Return a bunch of info about the timers. // Note that the returned info for these two functions may be different // on some platforms staticvoid current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr); staticvoid thread_cpu_time_info(jvmtiTimerInfo *info_ptr);
staticbool is_thread_cpu_time_supported();
// System loadavg support. Returns -1 if load average cannot be obtained. staticint loadavg(double loadavg[], int nelem);
// Amount beyond the callee frame size that we bang the stack. staticint extra_bang_size_in_bytes();
// Used to register dynamic code cache area with the OS // Note: Currently only used in 64 bit Windows implementations inlinestaticbool register_code_area(char *low, char *high);
// Platform-specific code for interacting with individual OSes. // TODO: This is for compatibility only with current usage of os::Linux, etc. // We can get rid of the following block if we rename such a class to something // like ::LinuxUtils #ifdefined(AIX) class Aix; #elifdefined(BSD) class Bsd; #elifdefined(LINUX) class Linux; #elifdefined(_WINDOWS) class win32; #endif
// Ditto - Posix-specific API. Ideally should be moved to something like ::PosixUtils. #ifndef _WINDOWS class Posix; #endif
// FIXME - some random stuff that was in os_windows.hpp #ifdef _WINDOWS // strtok_s is the Windows thread-safe equivalent of POSIX strtok_r # define strtok_r strtok_s # define S_ISCHR(mode) (((mode) & _S_IFCHR) == _S_IFCHR) # define S_ISFIFO(mode) (((mode) & _S_IFIFO) == _S_IFIFO) #endif
#ifndef OS_NATIVE_THREAD_CREATION_FAILED_MSG #define OS_NATIVE_THREAD_CREATION_FAILED_MSG "unable to create native thread: possibly out of memory or process/resource limits reached" #endif
public: inlinestaticbool platform_print_native_stack(outputStream* st, constvoid* context, char *buf, int buf_size);
// debugging support (mostly used by debug.cpp but also fatal error handler) staticbool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address
staticbool dont_yield(); // when true, JVM_Yield() is nop
// Thread priority helpers (implemented in OS-specific part) static OSReturn set_native_priority(Thread* thread, int native_prio); static OSReturn get_native_priority(const Thread* const thread, int* priority_ptr); staticint java_to_os_priority[CriticalPriority + 1]; // Hint to the underlying OS that a task switch would not be good. // Void return because it's a hint and can fail. staticconstchar* native_thread_creation_failed_msg() { return OS_NATIVE_THREAD_CREATION_FAILED_MSG;
}
// Used at creation if requested by the diagnostic flag PauseAtStartup. // Causes the VM to wait until an external stimulus has been applied // (for Unix, that stimulus is a signal, for Windows, an external // ResumeThread call) staticvoid pause();
// Builds a platform dependent Agent_OnLoad_<libname> function name // which is used to find statically linked in agents. staticchar* build_agent_function_name(constchar *sym, constchar *cname, bool is_absolute_path);
#ifdefined(__APPLE__) && defined(AARCH64) // Enables write or execute access to writeable and executable pages. staticvoid current_thread_enable_wx(WXMode mode); #endif// __APPLE__ && AARCH64
protected: staticvolatileunsignedint _rand_seed; // seed for random number generator staticint _processor_count; // number of processors staticint _initial_active_processor_count; // number of active processors during initialization.
// Note that "PAUSE" is almost always used with synchronization // so arguably we should provide Atomic::SpinPause() instead // of the global SpinPause() with C linkage. // It'd also be eligible for inlining on many platforms.
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.