os.hpp revision 9934:fd5d53ecf040
1112758Ssam/* 2112758Ssam * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 3112758Ssam * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4112758Ssam * 5112758Ssam * This code is free software; you can redistribute it and/or modify it 6112758Ssam * under the terms of the GNU General Public License version 2 only, as 7112758Ssam * published by the Free Software Foundation. 8112758Ssam * 9112758Ssam * This code is distributed in the hope that it will be useful, but WITHOUT 10112758Ssam * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11112758Ssam * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12112758Ssam * version 2 for more details (a copy is included in the LICENSE file that 13112758Ssam * accompanied this code). 14112758Ssam * 15112758Ssam * You should have received a copy of the GNU General Public License version 16112758Ssam * 2 along with this work; if not, write to the Free Software Foundation, 17112758Ssam * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18112758Ssam * 19112758Ssam * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20112758Ssam * or visit www.oracle.com if you need additional information or have any 21112758Ssam * questions. 22112758Ssam * 23112758Ssam */ 24112758Ssam 25112758Ssam#ifndef SHARE_VM_RUNTIME_OS_HPP 26112758Ssam#define SHARE_VM_RUNTIME_OS_HPP 27112758Ssam 28105197Ssam#include "jvmtifiles/jvmti.h" 29105197Ssam#include "runtime/extendedPC.hpp" 30105197Ssam#include "runtime/handles.hpp" 31105197Ssam#include "utilities/top.hpp" 32105197Ssam#ifdef TARGET_OS_FAMILY_linux 33105197Ssam# include "jvm_linux.h" 34105197Ssam# include <setjmp.h> 35159965Sthompsa#endif 36105197Ssam#ifdef TARGET_OS_FAMILY_solaris 37105197Ssam# include "jvm_solaris.h" 38105197Ssam# include <setjmp.h> 39105197Ssam#endif 40105197Ssam#ifdef TARGET_OS_FAMILY_windows 41105197Ssam# include "jvm_windows.h" 42105197Ssam#endif 43105197Ssam#ifdef TARGET_OS_FAMILY_aix 44105197Ssam# include "jvm_aix.h" 45105197Ssam# include <setjmp.h> 46105197Ssam#endif 47171497Sbz#ifdef TARGET_OS_FAMILY_bsd 48105197Ssam# include "jvm_bsd.h" 49195699Srwatson# include <setjmp.h> 50105197Ssam# ifdef __APPLE__ 51105197Ssam# include <mach/mach_time.h> 52105197Ssam# endif 53105197Ssam#endif 54105197Ssam 55105197Ssamclass AgentLibrary; 56105197Ssam 57105197Ssam// os defines the interface to operating system; this includes traditional 58105197Ssam// OS services (time, I/O) as well as other functionality with system- 59105197Ssam// dependent code. 60105197Ssam 61105197Ssamtypedef void (*dll_func)(...); 62105197Ssam 63105197Ssamclass Thread; 64105197Ssamclass JavaThread; 65105197Ssamclass Event; 66105197Ssamclass DLL; 67105197Ssamclass FileHandle; 68105197Ssamclass NativeCallStack; 69105197Ssam 70105197Ssamtemplate<class E> class GrowableArray; 71105197Ssam 72105197Ssam// %%%%% Moved ThreadState, START_FN, OSThread to new osThread.hpp. -- Rose 73105197Ssam 74105197Ssam// Platform-independent error return values from OS functions 75105197Ssamenum OSReturn { 76105197Ssam OS_OK = 0, // Operation was successful 77105197Ssam OS_ERR = -1, // Operation failed 78105197Ssam OS_INTRPT = -2, // Operation was interrupted 79105197Ssam OS_TIMEOUT = -3, // Operation timed out 80105197Ssam OS_NOMEM = -5, // Operation failed for lack of memory 81105197Ssam OS_NORESOURCE = -6 // Operation failed for lack of nonmemory resource 82105197Ssam}; 83105197Ssam 84105197Ssamenum ThreadPriority { // JLS 20.20.1-3 85105197Ssam NoPriority = -1, // Initial non-priority value 86194062Svanhu MinPriority = 1, // Minimum priority 87194062Svanhu NormPriority = 5, // Normal (non-daemon) priority 88194062Svanhu NearMaxPriority = 9, // High priority, used for VMThread 89194062Svanhu MaxPriority = 10, // Highest priority, used for WatcherThread 90181627Svanhu // ensures that VMThread doesn't starve profiler 91181627Svanhu CriticalPriority = 11 // Critical thread priority 92181627Svanhu}; 93181627Svanhu 94181627Svanhu// Executable parameter flag for os::commit_memory() and 95105197Ssam// os::commit_memory_or_exit(). 96105197Ssamconst bool ExecMem = true; 97105197Ssam 98105197Ssam// Typedef for structured exception handling support 99105197Ssamtypedef void (*java_call_t)(JavaValue* value, const methodHandle& method, JavaCallArguments* args, Thread* thread); 100105197Ssam 101105197Ssamclass MallocTracker; 102105197Ssam 103105197Ssamclass os: AllStatic { 104120585Ssam friend class VMStructs; 105120585Ssam friend class MallocTracker; 106105197Ssam public: 107120585Ssam enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel) 108120585Ssam 109105197Ssam private: 110105197Ssam static OSThread* _starting_thread; 111105197Ssam static address _polling_page; 112105197Ssam static volatile int32_t * _mem_serialize_page; 113105197Ssam static uintptr_t _serialize_page_mask; 114105197Ssam public: 115105197Ssam static size_t _page_sizes[page_sizes_max]; 116105197Ssam 117105197Ssam private: 118105197Ssam static void init_page_sizes(size_t default_page_size) { 119105197Ssam _page_sizes[0] = default_page_size; 120105197Ssam _page_sizes[1] = 0; // sentinel 121105197Ssam } 122105197Ssam 123105197Ssam static char* pd_reserve_memory(size_t bytes, char* addr = 0, 124105197Ssam size_t alignment_hint = 0); 125105197Ssam static char* pd_attempt_reserve_memory_at(size_t bytes, char* addr); 126105197Ssam static void pd_split_reserved_memory(char *base, size_t size, 127105197Ssam size_t split, bool realloc); 128105197Ssam static bool pd_commit_memory(char* addr, size_t bytes, bool executable); 129105197Ssam static bool pd_commit_memory(char* addr, size_t size, size_t alignment_hint, 130105197Ssam bool executable); 131105197Ssam // Same as pd_commit_memory() that either succeeds or calls 132105197Ssam // vm_exit_out_of_memory() with the specified mesg. 133105197Ssam static void pd_commit_memory_or_exit(char* addr, size_t bytes, 134105197Ssam bool executable, const char* mesg); 135120585Ssam static void pd_commit_memory_or_exit(char* addr, size_t size, 136105197Ssam size_t alignment_hint, 137105197Ssam bool executable, const char* mesg); 138105197Ssam static bool pd_uncommit_memory(char* addr, size_t bytes); 139105197Ssam static bool pd_release_memory(char* addr, size_t bytes); 140105197Ssam 141105197Ssam static char* pd_map_memory(int fd, const char* file_name, size_t file_offset, 142105197Ssam char *addr, size_t bytes, bool read_only = false, 143105197Ssam bool allow_exec = false); 144105197Ssam static char* pd_remap_memory(int fd, const char* file_name, size_t file_offset, 145105197Ssam char *addr, size_t bytes, bool read_only, 146105197Ssam bool allow_exec); 147105197Ssam static bool pd_unmap_memory(char *addr, size_t bytes); 148120585Ssam static void pd_free_memory(char *addr, size_t bytes, size_t alignment_hint); 149105197Ssam static void pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint); 150105197Ssam 151105197Ssam static size_t page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned); 152105197Ssam 153105197Ssam // Get summary strings for system information in buffer provided 154105197Ssam static bool get_host_name(char* buf, size_t buflen) PRODUCT_RETURN_(return false;); // true if available 155105197Ssam static void get_summary_cpu_info(char* buf, size_t buflen); 156105197Ssam static void get_summary_os_info(char* buf, size_t buflen); 157105197Ssam 158105197Ssam public: 159105197Ssam static void init(void); // Called before command line parsing 160105197Ssam static void init_before_ergo(void); // Called after command line parsing 161105197Ssam // before VM ergonomics processing. 162105197Ssam static jint init_2(void); // Called after command line parsing 163105197Ssam // and VM ergonomics processing 164105197Ssam static void init_globals(void) { // Called from init_globals() in init.cpp 165105197Ssam init_globals_ext(); 166105197Ssam } 167181803Sbz 168238700Sbz // File names are case-insensitive on windows only 169221129Sbz // Override me as needed 170221129Sbz static int file_name_strcmp(const char* s1, const char* s2); 171221129Sbz 172221129Sbz // unset environment variable 173221129Sbz static bool unsetenv(const char* name); 174221129Sbz 175221129Sbz static bool have_special_privileges(); 176221129Sbz 177221129Sbz static jlong javaTimeMillis(); 178221129Sbz static jlong javaTimeNanos(); 179221129Sbz static void javaTimeNanos_info(jvmtiTimerInfo *info_ptr); 180221129Sbz static void javaTimeSystemUTC(jlong &seconds, jlong &nanos); 181221129Sbz static void run_periodic_checks(); 182221129Sbz static bool supports_monotonic_clock(); 183221129Sbz 184221129Sbz // Returns the elapsed time in seconds since the vm started. 185221129Sbz static double elapsedTime(); 186221129Sbz 187221129Sbz // Returns real time in seconds since an arbitrary point 188221129Sbz // in the past. 189221129Sbz static bool getTimesSecs(double* process_real_time, 190105197Ssam double* process_user_time, 191117056Ssam double* process_system_time); 192105197Ssam 193223637Sbz // Interface to the performance counter 194223637Sbz static jlong elapsed_counter(); 195105197Ssam static jlong elapsed_frequency(); 196105197Ssam 197105197Ssam // The "virtual time" of a thread is the amount of time a thread has 198105197Ssam // actually run. The first function indicates whether the OS supports 199105197Ssam // this functionality for the current thread, and if so: 200105197Ssam // * the second enables vtime tracking (if that is required). 201105197Ssam // * the third tells whether vtime is enabled. 202105197Ssam // * the fourth returns the elapsed virtual time for the current 203105197Ssam // thread. 204105197Ssam static bool supports_vtime(); 205105197Ssam static bool enable_vtime(); 206105197Ssam static bool vtime_enabled(); 207105197Ssam static double elapsedVTime(); 208194062Svanhu 209194062Svanhu // Return current local time in a string (YYYY-MM-DD HH:MM:SS). 210194062Svanhu // It is MT safe, but not async-safe, as reading time zone 211194062Svanhu // information may require a lock on some platforms. 212194062Svanhu static char* local_time_string(char *buf, size_t buflen); 213194062Svanhu static struct tm* localtime_pd (const time_t* clock, struct tm* res); 214194062Svanhu // Fill in buffer with current local time as an ISO-8601 string. 215194062Svanhu // E.g., YYYY-MM-DDThh:mm:ss.mmm+zzzz. 216194062Svanhu // Returns buffer, or NULL if it failed. 217194062Svanhu static char* iso8601_time(char* buffer, size_t buffer_length); 218194062Svanhu 219194062Svanhu // Interface for detecting multiprocessor system 220194062Svanhu static inline bool is_MP() { 221194062Svanhu // During bootstrap if _processor_count is not yet initialized 222194062Svanhu // we claim to be MP as that is safest. If any platform has a 223194062Svanhu // stub generator that might be triggered in this phase and for 224194062Svanhu // which being declared MP when in fact not, is a problem - then 225194062Svanhu // the bootstrap routine for the stub generator needs to check 226194062Svanhu // the processor count directly and leave the bootstrap routine 227194062Svanhu // in place until called after initialization has ocurred. 228194062Svanhu return (_processor_count != 1) || AssumeMP; 229194062Svanhu } 230194062Svanhu static julong available_memory(); 231194062Svanhu static julong physical_memory(); 232194062Svanhu static bool has_allocatable_memory_limit(julong* limit); 233194062Svanhu static bool is_server_class_machine(); 234194062Svanhu 235194062Svanhu // number of CPUs 236194062Svanhu static int processor_count() { 237194062Svanhu return _processor_count; 238194062Svanhu } 239194062Svanhu static void set_processor_count(int count) { _processor_count = count; } 240194062Svanhu 241194062Svanhu // Returns the number of CPUs this process is currently allowed to run on. 242194062Svanhu // Note that on some OSes this can change dynamically. 243194062Svanhu static int active_processor_count(); 244194062Svanhu 245194062Svanhu // Bind processes to processors. 246194062Svanhu // This is a two step procedure: 247194062Svanhu // first you generate a distribution of processes to processors, 248194062Svanhu // then you bind processes according to that distribution. 249194062Svanhu // Compute a distribution for number of processes to processors. 250194062Svanhu // Stores the processor id's into the distribution array argument. 251194062Svanhu // Returns true if it worked, false if it didn't. 252194062Svanhu static bool distribute_processes(uint length, uint* distribution); 253194062Svanhu // Binds the current process to a processor. 254194062Svanhu // Returns true if it worked, false if it didn't. 255194062Svanhu static bool bind_to_processor(uint processor_id); 256194062Svanhu 257194062Svanhu // Give a name to the current thread. 258194062Svanhu static void set_native_thread_name(const char *name); 259105197Ssam 260105197Ssam // Interface for stack banging (predetect possible stack overflow for 261105197Ssam // exception processing) There are guard pages, and above that shadow 262105197Ssam // pages for stack overflow checking. 263105197Ssam static bool uses_stack_guard_pages(); 264105197Ssam static bool allocate_stack_guard_pages(); 265105197Ssam static void map_stack_shadow_pages(); 266105197Ssam static bool stack_shadow_pages_available(Thread *thread, const methodHandle& method); 267105197Ssam 268105197Ssam // OS interface to Virtual Memory 269105197Ssam 270105197Ssam // Return the default page size. 271105197Ssam static int vm_page_size(); 272105197Ssam 273105197Ssam // Returns the page size to use for a region of memory. 274105197Ssam // region_size / min_pages will always be greater than or equal to the 275105197Ssam // returned value. The returned value will divide region_size. 276105197Ssam static size_t page_size_for_region_aligned(size_t region_size, size_t min_pages); 277105197Ssam 278105197Ssam // Returns the page size to use for a region of memory. 279105197Ssam // region_size / min_pages will always be greater than or equal to the 280105197Ssam // returned value. The returned value might not divide region_size. 281105197Ssam static size_t page_size_for_region_unaligned(size_t region_size, size_t min_pages); 282105197Ssam 283105197Ssam // Return the largest page size that can be used 284105197Ssam static size_t max_page_size() { 285105197Ssam // The _page_sizes array is sorted in descending order. 286105197Ssam return _page_sizes[0]; 287105197Ssam } 288105197Ssam 289120585Ssam // Methods for tracing page sizes returned by the above method; enabled by 290120585Ssam // TracePageSizes. The region_{min,max}_size parameters should be the values 291120585Ssam // passed to page_size_for_region() and page_size should be the result of that 292120585Ssam // call. The (optional) base and size parameters should come from the 293105197Ssam // ReservedSpace base() and size() methods. 294105197Ssam static void trace_page_sizes(const char* str, const size_t* page_sizes, 295105197Ssam int count) PRODUCT_RETURN; 296105197Ssam static void trace_page_sizes(const char* str, const size_t region_min_size, 297105197Ssam const size_t region_max_size, 298105197Ssam const size_t page_size, 299105197Ssam const char* base = NULL, 300105197Ssam const size_t size = 0) PRODUCT_RETURN; 301105197Ssam 302105197Ssam static int vm_allocation_granularity(); 303105197Ssam static char* reserve_memory(size_t bytes, char* addr = 0, 304105197Ssam size_t alignment_hint = 0); 305105197Ssam static char* reserve_memory(size_t bytes, char* addr, 306105197Ssam size_t alignment_hint, MEMFLAGS flags); 307105197Ssam static char* reserve_memory_aligned(size_t size, size_t alignment); 308105197Ssam static char* attempt_reserve_memory_at(size_t bytes, char* addr); 309105197Ssam static void split_reserved_memory(char *base, size_t size, 310105197Ssam size_t split, bool realloc); 311105197Ssam static bool commit_memory(char* addr, size_t bytes, bool executable); 312105197Ssam static bool commit_memory(char* addr, size_t size, size_t alignment_hint, 313105197Ssam bool executable); 314105197Ssam // Same as commit_memory() that either succeeds or calls 315105197Ssam // vm_exit_out_of_memory() with the specified mesg. 316105197Ssam static void commit_memory_or_exit(char* addr, size_t bytes, 317105197Ssam bool executable, const char* mesg); 318105197Ssam static void commit_memory_or_exit(char* addr, size_t size, 319105197Ssam size_t alignment_hint, 320105197Ssam bool executable, const char* mesg); 321105197Ssam static bool uncommit_memory(char* addr, size_t bytes); 322105197Ssam static bool release_memory(char* addr, size_t bytes); 323105197Ssam 324105197Ssam // Touch memory pages that cover the memory range from start to end (exclusive) 325105197Ssam // to make the OS back the memory range with actual memory. 326105197Ssam // Current implementation may not touch the last page if unaligned addresses 327105197Ssam // are passed. 328105197Ssam static void pretouch_memory(char* start, char* end); 329105197Ssam 330105197Ssam enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX }; 331105197Ssam static bool protect_memory(char* addr, size_t bytes, ProtType prot, 332105197Ssam bool is_committed = true); 333105197Ssam 334105197Ssam static bool guard_memory(char* addr, size_t bytes); 335105197Ssam static bool unguard_memory(char* addr, size_t bytes); 336105197Ssam static bool create_stack_guard_pages(char* addr, size_t bytes); 337105197Ssam static bool pd_create_stack_guard_pages(char* addr, size_t bytes); 338105197Ssam static bool remove_stack_guard_pages(char* addr, size_t bytes); 339105197Ssam 340105197Ssam static char* map_memory(int fd, const char* file_name, size_t file_offset, 341105197Ssam char *addr, size_t bytes, bool read_only = false, 342105197Ssam bool allow_exec = false); 343105197Ssam static char* remap_memory(int fd, const char* file_name, size_t file_offset, 344105197Ssam char *addr, size_t bytes, bool read_only, 345105197Ssam bool allow_exec); 346105197Ssam static bool unmap_memory(char *addr, size_t bytes); 347105197Ssam static void free_memory(char *addr, size_t bytes, size_t alignment_hint); 348105197Ssam static void realign_memory(char *addr, size_t bytes, size_t alignment_hint); 349105197Ssam 350105197Ssam // NUMA-specific interface 351105197Ssam static bool numa_has_static_binding(); 352105197Ssam static bool numa_has_group_homing(); 353105197Ssam static void numa_make_local(char *addr, size_t bytes, int lgrp_hint); 354105197Ssam static void numa_make_global(char *addr, size_t bytes); 355105197Ssam static size_t numa_get_groups_num(); 356105197Ssam static size_t numa_get_leaf_groups(int *ids, size_t size); 357105197Ssam static bool numa_topology_changed(); 358105197Ssam static int numa_get_group_id(); 359105197Ssam 360105197Ssam // Page manipulation 361105197Ssam struct page_info { 362105197Ssam size_t size; 363105197Ssam int lgrp_id; 364105197Ssam }; 365181803Sbz static bool get_page_info(char *start, page_info* info); 366105197Ssam static char* scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found); 367105197Ssam 368105197Ssam static char* non_memory_address_word(); 369177175Sbz // reserve, commit and pin the entire memory region 370120585Ssam static char* reserve_memory_special(size_t size, size_t alignment, 371120585Ssam char* addr, bool executable); 372105197Ssam static bool release_memory_special(char* addr, size_t bytes); 373120585Ssam static void large_page_init(); 374105197Ssam static size_t large_page_size(); 375177175Sbz static bool can_commit_large_page_memory(); 376177175Sbz static bool can_execute_large_page_memory(); 377177175Sbz 378177175Sbz // OS interface to polling page 379177175Sbz static address get_polling_page() { return _polling_page; } 380177175Sbz static void set_polling_page(address page) { _polling_page = page; } 381105197Ssam static bool is_poll_address(address addr) { return addr >= _polling_page && addr < (_polling_page + os::vm_page_size()); } 382120585Ssam static void make_polling_page_unreadable(); 383105197Ssam static void make_polling_page_readable(); 384105197Ssam 385105197Ssam // Routines used to serialize the thread state without using membars 386105197Ssam static void serialize_thread_states(); 387105197Ssam 388105197Ssam // Since we write to the serialize page from every thread, we 389181803Sbz // want stores to be on unique cache lines whenever possible 390181803Sbz // in order to minimize CPU cross talk. We pre-compute the 391181803Sbz // amount to shift the thread* to make this offset unique to 392120585Ssam // each thread. 393120585Ssam static int get_serialize_page_shift_count() { 394181803Sbz return SerializePageShiftCount; 395181803Sbz } 396105197Ssam 397105197Ssam static void set_serialize_page_mask(uintptr_t mask) { 398105197Ssam _serialize_page_mask = mask; 399105197Ssam } 400105197Ssam 401105197Ssam static unsigned int get_serialize_page_mask() { 402105197Ssam return _serialize_page_mask; 403105197Ssam } 404105197Ssam 405120585Ssam static void set_memory_serialize_page(address page); 406181803Sbz 407181803Sbz static address get_memory_serialize_page() { 408105197Ssam return (address)_mem_serialize_page; 409105197Ssam } 410105197Ssam 411105197Ssam static inline void write_memory_serialize_page(JavaThread *thread) { 412105197Ssam uintptr_t page_offset = ((uintptr_t)thread >> 413120585Ssam get_serialize_page_shift_count()) & 414120585Ssam get_serialize_page_mask(); 415105197Ssam *(volatile int32_t *)((uintptr_t)_mem_serialize_page+page_offset) = 1; 416105197Ssam } 417105197Ssam 418105197Ssam static bool is_memory_serialize_page(JavaThread *thread, address addr) { 419105197Ssam if (UseMembar) return false; 420105197Ssam // Previously this function calculated the exact address of this 421105197Ssam // thread's serialize page, and checked if the faulting address 422105197Ssam // was equal. However, some platforms mask off faulting addresses 423105197Ssam // to the page size, so now we just check that the address is 424105197Ssam // within the page. This makes the thread argument unnecessary, 425105197Ssam // but we retain the NULL check to preserve existing behavior. 426105197Ssam if (thread == NULL) return false; 427105197Ssam address page = (address) _mem_serialize_page; 428105197Ssam return addr >= page && addr < (page + os::vm_page_size()); 429105197Ssam } 430105197Ssam 431105197Ssam static void block_on_serialize_page_trap(); 432105197Ssam 433119643Ssam // threads 434105197Ssam 435120585Ssam enum ThreadType { 436120585Ssam vm_thread, 437105197Ssam cgc_thread, // Concurrent GC thread 438120585Ssam pgc_thread, // Parallel GC thread 439105197Ssam java_thread, 440105197Ssam compiler_thread, 441177175Sbz watcher_thread, 442177175Sbz os_thread 443177175Sbz }; 444177175Sbz 445177175Sbz static bool create_thread(Thread* thread, 446105197Ssam ThreadType thr_type, 447105197Ssam size_t stack_size = 0); 448159965Sthompsa static bool create_main_thread(JavaThread* thread); 449159965Sthompsa static bool create_attached_thread(JavaThread* thread); 450181627Svanhu static void pd_start_thread(Thread* thread); 451181627Svanhu static void start_thread(Thread* thread); 452181627Svanhu 453174054Sbz static void initialize_thread(Thread* thr); 454174054Sbz static void free_thread(OSThread* osthread); 455159965Sthompsa 456174054Sbz // thread id on Linux/64bit is 64bit, on Windows and Solaris, it's 32bit 457159965Sthompsa static intx current_thread_id(); 458159965Sthompsa static int current_process_id(); 459159965Sthompsa static int sleep(Thread* thread, jlong ms, bool interruptable); 460105197Ssam // Short standalone OS sleep suitable for slow path spin loop. 461105197Ssam // Ignores Thread.interrupt() (so keep it short). 462105197Ssam // ms = 0, will sleep for the least amount of time allowed by the OS. 463105197Ssam static void naked_short_sleep(jlong ms); 464105197Ssam static void infinite_sleep(); // never returns, use with CAUTION 465105197Ssam static void naked_yield () ; 466105197Ssam static OSReturn set_priority(Thread* thread, ThreadPriority priority); 467105197Ssam static OSReturn get_priority(const Thread* const thread, ThreadPriority& priority); 468105197Ssam 469105197Ssam static void interrupt(Thread* thread); 470105197Ssam static bool is_interrupted(Thread* thread, bool clear_interrupted); 471105197Ssam 472105197Ssam static int pd_self_suspend_thread(Thread* thread); 473105197Ssam 474105197Ssam static ExtendedPC fetch_frame_from_context(const void* ucVoid, intptr_t** sp, intptr_t** fp); 475181803Sbz static frame fetch_frame_from_context(const void* ucVoid); 476105197Ssam static frame fetch_frame_from_ucontext(Thread* thread, void* ucVoid); 477105197Ssam 478181803Sbz static ExtendedPC get_thread_pc(Thread *thread); 479105197Ssam static void breakpoint(); 480105197Ssam static bool start_debugging(char *buf, int buflen); 481105197Ssam 482105197Ssam static address current_stack_pointer(); 483105197Ssam static address current_stack_base(); 484105197Ssam static size_t current_stack_size(); 485105197Ssam 486105197Ssam static void verify_stack_alignment() PRODUCT_RETURN; 487105197Ssam 488105197Ssam static bool message_box(const char* title, const char* message); 489105197Ssam static char* do_you_want_to_debug(const char* message); 490105197Ssam 491105197Ssam // run cmd in a separate process and return its exit code; or -1 on failures 492105197Ssam static int fork_and_exec(char *cmd); 493105197Ssam 494105197Ssam // Call ::exit() on all platforms but Windows 495105197Ssam static void exit(int num); 496105197Ssam 497105197Ssam // Terminate the VM, but don't exit the process 498105197Ssam static void shutdown(); 499105197Ssam 500105197Ssam // Terminate with an error. Default is to generate a core file on platforms 501105197Ssam // that support such things. This calls shutdown() and then aborts. 502105197Ssam static void abort(bool dump_core, void *siginfo, const void *context); 503105197Ssam static void abort(bool dump_core = true); 504105197Ssam 505105197Ssam // Die immediately, no exit hook, no abort hook, no cleanup. 506105197Ssam static void die(); 507105197Ssam 508105197Ssam // File i/o operations 509105197Ssam static const int default_file_open_flags(); 510105197Ssam static int open(const char *path, int oflag, int mode); 511105197Ssam static FILE* open(int fd, const char* mode); 512105197Ssam static int close(int fd); 513105197Ssam static jlong lseek(int fd, jlong offset, int whence); 514105197Ssam static char* native_path(char *path); 515105197Ssam static int ftruncate(int fd, jlong length); 516105197Ssam static int fsync(int fd); 517105197Ssam static int available(int fd, jlong *bytes); 518105197Ssam 519105197Ssam //File i/o operations 520105197Ssam 521105197Ssam static size_t read(int fd, void *buf, unsigned int nBytes); 522105197Ssam static size_t read_at(int fd, void *buf, unsigned int nBytes, jlong offset); 523120585Ssam static size_t restartable_read(int fd, void *buf, unsigned int nBytes); 524120585Ssam static size_t write(int fd, const void *buf, unsigned int nBytes); 525105197Ssam 526105197Ssam // Reading directories. 527105197Ssam static DIR* opendir(const char* dirname); 528124765Ssam static int readdir_buf_size(const char *path); 529124765Ssam static struct dirent* readdir(DIR* dirp, dirent* dbuf); 530105197Ssam static int closedir(DIR* dirp); 531124765Ssam 532124765Ssam // Dynamic library extension 533105197Ssam static const char* dll_file_extension(); 534105197Ssam 535105197Ssam static const char* get_temp_directory(); 536105197Ssam static const char* get_current_directory(char *buf, size_t buflen); 537105197Ssam 538105197Ssam // Builds a platform-specific full library path given a ld path and lib name 539105197Ssam // Returns true if buffer contains full path to existing file, false otherwise 540105197Ssam static bool dll_build_name(char* buffer, size_t size, 541105197Ssam const char* pathname, const char* fname); 542105197Ssam 543105197Ssam // Symbol lookup, find nearest function name; basically it implements 544105197Ssam // dladdr() for all platforms. Name of the nearest function is copied 545105197Ssam // to buf. Distance from its base address is optionally returned as offset. 546105197Ssam // If function name is not found, buf[0] is set to '\0' and offset is 547105197Ssam // set to -1 (if offset is non-NULL). 548105197Ssam static bool dll_address_to_function_name(address addr, char* buf, 549105197Ssam int buflen, int* offset, 550105197Ssam bool demangle = true); 551105197Ssam 552105197Ssam // Locate DLL/DSO. On success, full path of the library is copied to 553105197Ssam // buf, and offset is optionally set to be the distance between addr 554105197Ssam // and the library's base address. On failure, buf[0] is set to '\0' 555105197Ssam // and offset is set to -1 (if offset is non-NULL). 556105197Ssam static bool dll_address_to_library_name(address addr, char* buf, 557159965Sthompsa int buflen, int* offset); 558159965Sthompsa 559174054Sbz // Find out whether the pc is in the static code for jvm.dll/libjvm.so. 560174054Sbz static bool address_is_in_vm(address addr); 561174054Sbz 562174054Sbz // Loads .dll/.so and 563159965Sthompsa // in case of error it checks if .dll/.so was built for the 564159965Sthompsa // same architecture as HotSpot is running on 565105197Ssam static void* dll_load(const char *name, char *ebuf, int ebuflen); 566105197Ssam 567105197Ssam // lookup symbol in a shared library 568105197Ssam static void* dll_lookup(void* handle, const char* name); 569105197Ssam 570105197Ssam // Unload library 571105197Ssam static void dll_unload(void *lib); 572105197Ssam 573105197Ssam // Callback for loaded module information 574105197Ssam // Input parameters: 575105197Ssam // char* module_file_name, 576105197Ssam // address module_base_addr, 577105197Ssam // address module_top_addr, 578105197Ssam // void* param 579105197Ssam typedef int (*LoadedModulesCallbackFunc)(const char *, address, address, void *); 580105197Ssam 581105197Ssam static int get_loaded_modules_info(LoadedModulesCallbackFunc callback, void *param); 582105197Ssam 583120585Ssam // Return the handle of this process 584105197Ssam static void* get_default_process_handle(); 585105197Ssam 586120585Ssam // Check for static linked agent library 587120585Ssam static bool find_builtin_agent(AgentLibrary *agent_lib, const char *syms[], 588105197Ssam size_t syms_len); 589105197Ssam 590105197Ssam // Find agent entry point 591105197Ssam static void *find_agent_function(AgentLibrary *agent_lib, bool check_lib, 592105197Ssam const char *syms[], size_t syms_len); 593105197Ssam 594105197Ssam // Write to stream 595105197Ssam static int log_vsnprintf(char* buf, size_t len, const char* fmt, va_list args) ATTRIBUTE_PRINTF(3, 0); 596105197Ssam 597105197Ssam // Print out system information; they are called by fatal error handler. 598105197Ssam // Output format may be different on different platforms. 599105197Ssam static void print_os_info(outputStream* st); 600105197Ssam static void print_os_info_brief(outputStream* st); 601105197Ssam static void print_cpu_info(outputStream* st, char* buf, size_t buflen); 602105197Ssam static void pd_print_cpu_info(outputStream* st, char* buf, size_t buflen); 603105197Ssam static void print_summary_info(outputStream* st, char* buf, size_t buflen); 604105197Ssam static void print_memory_info(outputStream* st); 605120585Ssam static void print_dll_info(outputStream* st); 606120585Ssam static void print_environment_variables(outputStream* st, const char** env_list); 607105197Ssam static void print_context(outputStream* st, const void* context); 608105197Ssam static void print_register_info(outputStream* st, const void* context); 609105197Ssam static void print_siginfo(outputStream* st, const void* siginfo); 610151967Sandre static void print_signal_handlers(outputStream* st, char* buf, size_t buflen); 611105197Ssam static void print_date_and_time(outputStream* st, char* buf, size_t buflen); 612105197Ssam 613105197Ssam static void print_location(outputStream* st, intptr_t x, bool verbose = false); 614105197Ssam static size_t lasterror(char *buf, size_t len); 615108466Ssam static int get_last_error(); 616105197Ssam 617105197Ssam // Determines whether the calling process is being debugged by a user-mode debugger. 618105197Ssam static bool is_debugger_attached(); 619105197Ssam 620105197Ssam // wait for a key press if PauseAtExit is set 621105197Ssam static void wait_for_keypress_at_exit(void); 622105197Ssam 623105197Ssam // The following two functions are used by fatal error handler to trace 624105197Ssam // native (C) frames. They are not part of frame.hpp/frame.cpp because 625105197Ssam // frame.hpp/cpp assume thread is JavaThread, and also because different 626105197Ssam // OS/compiler may have different convention or provide different API to 627105197Ssam // walk C frames. 628105197Ssam // 629105197Ssam // We don't attempt to become a debugger, so we only follow frames if that 630105197Ssam // does not require a lookup in the unwind table, which is part of the binary 631105197Ssam // file but may be unsafe to read after a fatal error. So on x86, we can 632105197Ssam // only walk stack if %ebp is used as frame pointer; on ia64, it's not 633105197Ssam // possible to walk C stack without having the unwind table. 634105197Ssam static bool is_first_C_frame(frame *fr); 635105197Ssam static frame get_sender_for_C_frame(frame *fr); 636105197Ssam 637105197Ssam // return current frame. pc() and sp() are set to NULL on failure. 638105197Ssam static frame current_frame(); 639105197Ssam 640105197Ssam static void print_hex_dump(outputStream* st, address start, address end, int unitsize); 641105197Ssam 642105197Ssam // returns a string to describe the exception/signal; 643105197Ssam // returns NULL if exception_code is not an OS exception/signal. 644105197Ssam static const char* exception_name(int exception_code, char* buf, size_t buflen); 645105197Ssam 646105197Ssam // Returns the signal number (e.g. 11) for a given signal name (SIGSEGV). 647105197Ssam static int get_signal_number(const char* signal_name); 648120585Ssam 649120585Ssam // Returns native Java library, loads if necessary 650120585Ssam static void* native_java_library(); 651120585Ssam 652120585Ssam // Fills in path to jvm.dll/libjvm.so (used by the Disassembler) 653120585Ssam static void jvm_path(char *buf, jint buflen); 654105197Ssam 655105197Ssam // Returns true if we are running in a headless jre. 656170122Sbz static bool is_headless_jre(); 657105197Ssam 658105197Ssam // JNI names 659105197Ssam static void print_jni_name_prefix_on(outputStream* st, int args_size); 660105197Ssam static void print_jni_name_suffix_on(outputStream* st, int args_size); 661105197Ssam 662105197Ssam // Init os specific system properties values 663105197Ssam static void init_system_properties_values(); 664105197Ssam 665105197Ssam // IO operations, non-JVM_ version. 666105197Ssam static int stat(const char* path, struct stat* sbuf); 667105197Ssam static bool dir_is_empty(const char* path); 668105197Ssam 669171133Sgnn // IO operations on binary files 670105197Ssam static int create_binary_file(const char* path, bool rewrite_existing); 671105197Ssam static jlong current_file_offset(int fd); 672177175Sbz static jlong seek_to_file_offset(int fd, jlong offset); 673105197Ssam 674177175Sbz // Retrieve native stack frames. 675177175Sbz // Parameter: 676177175Sbz // stack: an array to storage stack pointers. 677177175Sbz // frames: size of above array. 678177175Sbz // toSkip: number of stack frames to skip at the beginning. 679177175Sbz // Return: number of stack frames captured. 680177175Sbz static int get_native_stack(address* stack, int size, int toSkip = 0); 681177175Sbz 682177175Sbz // General allocation (must be MT-safe) 683177175Sbz static void* malloc (size_t size, MEMFLAGS flags, const NativeCallStack& stack); 684177175Sbz static void* malloc (size_t size, MEMFLAGS flags); 685177175Sbz static void* realloc (void *memblock, size_t size, MEMFLAGS flag, const NativeCallStack& stack); 686105197Ssam static void* realloc (void *memblock, size_t size, MEMFLAGS flag); 687177175Sbz 688177175Sbz static void free (void *memblock); 689177175Sbz static bool check_heap(bool force = false); // verify C heap integrity 690105197Ssam static char* strdup(const char *, MEMFLAGS flags = mtInternal); // Like strdup 691105197Ssam // Like strdup, but exit VM when strdup() returns NULL 692171133Sgnn static char* strdup_check_oom(const char*, MEMFLAGS flags = mtInternal); 693171133Sgnn 694171133Sgnn#ifndef PRODUCT 695171133Sgnn static julong num_mallocs; // # of calls to malloc/realloc 696171133Sgnn static julong alloc_bytes; // # of bytes allocated 697171133Sgnn static julong num_frees; // # of calls to free 698105197Ssam static julong free_bytes; // # of bytes freed 699171133Sgnn#endif 700171133Sgnn 701105197Ssam // SocketInterface (ex HPI SocketInterface ) 702105197Ssam static int socket(int domain, int type, int protocol); 703105197Ssam static int socket_close(int fd); 704105197Ssam static int recv(int fd, char* buf, size_t nBytes, uint flags); 705105197Ssam static int send(int fd, char* buf, size_t nBytes, uint flags); 706105197Ssam static int raw_send(int fd, char* buf, size_t nBytes, uint flags); 707105197Ssam static int connect(int fd, struct sockaddr* him, socklen_t len); 708105197Ssam static struct hostent* get_host_by_name(char* name); 709105197Ssam 710105197Ssam // Support for signals (see JVM_RaiseSignal, JVM_RegisterSignal) 711105197Ssam static void signal_init(); 712105197Ssam static void signal_init_pd(); 713105197Ssam static void signal_notify(int signal_number); 714105197Ssam static void* signal(int signal_number, void* handler); 715105197Ssam static void signal_raise(int signal_number); 716105197Ssam static int signal_wait(); 717105197Ssam static int signal_lookup(); 718105197Ssam static void* user_handler(); 719105197Ssam static void terminate_signal_thread(); 720171133Sgnn static int sigexitnum_pd(); 721120585Ssam 722105197Ssam // random number generation 723105197Ssam static long random(); // return 32bit pseudorandom number 724105197Ssam static void init_random(long initval); // initialize random sequence 725105197Ssam 726105197Ssam // Structured OS Exception support 727105197Ssam static void os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method, JavaCallArguments* args, Thread* thread); 728105197Ssam 729105197Ssam // On Posix compatible OS it will simply check core dump limits while on Windows 730111119Simp // it will check if dump file can be created. Check or prepare a core dump to be 731105197Ssam // taken at a later point in the same thread in os::abort(). Use the caller 732105197Ssam // provided buffer as a scratch buffer. The status message which will be written 733105197Ssam // into the error log either is file location or a short error message, depending 734105197Ssam // on the checking result. 735105197Ssam static void check_dump_limit(char* buffer, size_t bufferSize); 736105197Ssam 737105197Ssam // Get the default path to the core file 738105197Ssam // Returns the length of the string 739105197Ssam static int get_core_path(char* buffer, size_t bufferSize); 740105197Ssam 741105197Ssam // JVMTI & JVM monitoring and management support 742105197Ssam // The thread_cpu_time() and current_thread_cpu_time() are only 743105197Ssam // supported if is_thread_cpu_time_supported() returns true. 744105197Ssam // They are not supported on Solaris T1. 745105197Ssam 746105197Ssam // Thread CPU Time - return the fast estimate on a platform 747113076Sdes // On Solaris - call gethrvtime (fast) - user time only 748105197Ssam // On Linux - fast clock_gettime where available - user+sys 749105197Ssam // - otherwise: very slow /proc fs - user+sys 750105197Ssam // On Windows - GetThreadTimes - user+sys 751105197Ssam static jlong current_thread_cpu_time(); 752105197Ssam static jlong thread_cpu_time(Thread* t); 753105197Ssam 754105197Ssam // Thread CPU Time with user_sys_cpu_time parameter. 755105197Ssam // 756105197Ssam // If user_sys_cpu_time is true, user+sys time is returned. 757181803Sbz // Otherwise, only user time is returned 758105197Ssam static jlong current_thread_cpu_time(bool user_sys_cpu_time); 759105197Ssam static jlong thread_cpu_time(Thread* t, bool user_sys_cpu_time); 760105197Ssam 761105197Ssam // Return a bunch of info about the timers. 762105197Ssam // Note that the returned info for these two functions may be different 763105197Ssam // on some platforms 764171133Sgnn static void current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr); 765171133Sgnn static void thread_cpu_time_info(jvmtiTimerInfo *info_ptr); 766105197Ssam 767105197Ssam static bool is_thread_cpu_time_supported(); 768105197Ssam 769105197Ssam // System loadavg support. Returns -1 if load average cannot be obtained. 770105197Ssam static int loadavg(double loadavg[], int nelem); 771105197Ssam 772105197Ssam // Hook for os specific jvm options that we don't want to abort on seeing 773105197Ssam static bool obsolete_option(const JavaVMOption *option); 774105197Ssam 775105197Ssam // Amount beyond the callee frame size that we bang the stack. 776105197Ssam static int extra_bang_size_in_bytes(); 777105197Ssam 778105197Ssam // Extensions 779105197Ssam#include "runtime/os_ext.hpp" 780105197Ssam 781105197Ssam public: 782105197Ssam class CrashProtectionCallback : public StackObj { 783213836Sbz public: 784105197Ssam virtual void call() = 0; 785105197Ssam }; 786120585Ssam 787120585Ssam // Platform dependent stuff 788120585Ssam#ifdef TARGET_OS_FAMILY_linux 789105197Ssam# include "os_linux.hpp" 790105197Ssam# include "os_posix.hpp" 791170122Sbz#endif 792105197Ssam#ifdef TARGET_OS_FAMILY_solaris 793105197Ssam# include "os_solaris.hpp" 794105197Ssam# include "os_posix.hpp" 795105197Ssam#endif 796105197Ssam#ifdef TARGET_OS_FAMILY_windows 797105197Ssam# include "os_windows.hpp" 798105197Ssam#endif 799105197Ssam#ifdef TARGET_OS_FAMILY_aix 800105197Ssam# include "os_aix.hpp" 801105197Ssam# include "os_posix.hpp" 802105197Ssam#endif 803170123Sbz#ifdef TARGET_OS_FAMILY_bsd 804170123Sbz# include "os_posix.hpp" 805105197Ssam# include "os_bsd.hpp" 806177175Sbz#endif 807177175Sbz#ifdef TARGET_OS_ARCH_linux_x86 808177175Sbz# include "os_linux_x86.hpp" 809177175Sbz#endif 810177175Sbz#ifdef TARGET_OS_ARCH_linux_sparc 811105197Ssam# include "os_linux_sparc.hpp" 812174054Sbz#endif 813181627Svanhu#ifdef TARGET_OS_ARCH_linux_zero 814181627Svanhu# include "os_linux_zero.hpp" 815181627Svanhu#endif 816174054Sbz#ifdef TARGET_OS_ARCH_solaris_x86 817174054Sbz# include "os_solaris_x86.hpp" 818174054Sbz#endif 819174054Sbz#ifdef TARGET_OS_ARCH_solaris_sparc 820174054Sbz# include "os_solaris_sparc.hpp" 821174054Sbz#endif 822174054Sbz#ifdef TARGET_OS_ARCH_windows_x86 823105197Ssam# include "os_windows_x86.hpp" 824105197Ssam#endif 825105197Ssam#ifdef TARGET_OS_ARCH_linux_arm 826105197Ssam# include "os_linux_arm.hpp" 827105197Ssam#endif 828105197Ssam#ifdef TARGET_OS_ARCH_linux_ppc 829105197Ssam# include "os_linux_ppc.hpp" 830105197Ssam#endif 831105197Ssam#ifdef TARGET_OS_ARCH_aix_ppc 832105197Ssam# include "os_aix_ppc.hpp" 833120585Ssam#endif 834120585Ssam#ifdef TARGET_OS_ARCH_linux_aarch64 835105197Ssam# include "os_linux_aarch64.hpp" 836181803Sbz#endif 837105197Ssam#ifdef TARGET_OS_ARCH_bsd_x86 838105197Ssam# include "os_bsd_x86.hpp" 839105197Ssam#endif 840105197Ssam#ifdef TARGET_OS_ARCH_bsd_zero 841105197Ssam# include "os_bsd_zero.hpp" 842105197Ssam#endif 843181803Sbz 844105197Ssam#ifndef OS_NATIVE_THREAD_CREATION_FAILED_MSG 845105197Ssam#define OS_NATIVE_THREAD_CREATION_FAILED_MSG "unable to create native thread: possibly out of memory or process/resource limits reached" 846105197Ssam#endif 847105197Ssam 848105197Ssam public: 849105197Ssam#ifndef PLATFORM_PRINT_NATIVE_STACK 850105197Ssam // No platform-specific code for printing the native stack. 851105197Ssam static bool platform_print_native_stack(outputStream* st, const void* context, 852105197Ssam char *buf, int buf_size) { 853105197Ssam return false; 854214250Sbz } 855214250Sbz#endif 856105197Ssam 857105197Ssam // debugging support (mostly used by debug.cpp but also fatal error handler) 858105197Ssam static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address 859105197Ssam 860105197Ssam static bool dont_yield(); // when true, JVM_Yield() is nop 861105197Ssam static void print_statistics(); 862105197Ssam 863105197Ssam // Thread priority helpers (implemented in OS-specific part) 864187936Sbz static OSReturn set_native_priority(Thread* thread, int native_prio); 865105197Ssam static OSReturn get_native_priority(const Thread* const thread, int* priority_ptr); 866105197Ssam static int java_to_os_priority[CriticalPriority + 1]; 867105197Ssam // Hint to the underlying OS that a task switch would not be good. 868105197Ssam // Void return because it's a hint and can fail. 869231852Sbz static void hint_no_preempt(); 870105197Ssam static const char* native_thread_creation_failed_msg() { 871187936Sbz return OS_NATIVE_THREAD_CREATION_FAILED_MSG; 872181803Sbz } 873181803Sbz 874105197Ssam // Used at creation if requested by the diagnostic flag PauseAtStartup. 875105197Ssam // Causes the VM to wait until an external stimulus has been applied 876105197Ssam // (for Unix, that stimulus is a signal, for Windows, an external 877105197Ssam // ResumeThread call) 878105197Ssam static void pause(); 879213837Sbz 880105197Ssam // Builds a platform dependent Agent_OnLoad_<libname> function name 881105197Ssam // which is used to find statically linked in agents. 882105197Ssam static char* build_agent_function_name(const char *sym, const char *cname, 883105197Ssam bool is_absolute_path); 884105197Ssam 885181803Sbz class SuspendedThreadTaskContext { 886105197Ssam public: 887105197Ssam SuspendedThreadTaskContext(Thread* thread, void *ucontext) : _thread(thread), _ucontext(ucontext) {} 888105197Ssam Thread* thread() const { return _thread; } 889105197Ssam void* ucontext() const { return _ucontext; } 890174054Sbz private: 891174054Sbz Thread* _thread; 892174054Sbz void* _ucontext; 893174054Sbz }; 894174054Sbz 895174054Sbz class SuspendedThreadTask { 896174054Sbz public: 897174054Sbz SuspendedThreadTask(Thread* thread) : _thread(thread), _done(false) {} 898174054Sbz virtual ~SuspendedThreadTask() {} 899170123Sbz void run(); 900105197Ssam bool is_done() { return _done; } 901105197Ssam virtual void do_task(const SuspendedThreadTaskContext& context) = 0; 902170123Sbz protected: 903170123Sbz private: 904105197Ssam void internal_do_task(); 905170123Sbz Thread* _thread; 906170123Sbz bool _done; 907105197Ssam }; 908105197Ssam 909105197Ssam#ifndef TARGET_OS_FAMILY_windows 910105197Ssam // Suspend/resume support 911105197Ssam // Protocol: 912105197Ssam // 913 // a thread starts in SR_RUNNING 914 // 915 // SR_RUNNING can go to 916 // * SR_SUSPEND_REQUEST when the WatcherThread wants to suspend it 917 // SR_SUSPEND_REQUEST can go to 918 // * SR_RUNNING if WatcherThread decides it waited for SR_SUSPENDED too long (timeout) 919 // * SR_SUSPENDED if the stopped thread receives the signal and switches state 920 // SR_SUSPENDED can go to 921 // * SR_WAKEUP_REQUEST when the WatcherThread has done the work and wants to resume 922 // SR_WAKEUP_REQUEST can go to 923 // * SR_RUNNING when the stopped thread receives the signal 924 // * SR_WAKEUP_REQUEST on timeout (resend the signal and try again) 925 class SuspendResume { 926 public: 927 enum State { 928 SR_RUNNING, 929 SR_SUSPEND_REQUEST, 930 SR_SUSPENDED, 931 SR_WAKEUP_REQUEST 932 }; 933 934 private: 935 volatile State _state; 936 937 private: 938 /* try to switch state from state "from" to state "to" 939 * returns the state set after the method is complete 940 */ 941 State switch_state(State from, State to); 942 943 public: 944 SuspendResume() : _state(SR_RUNNING) { } 945 946 State state() const { return _state; } 947 948 State request_suspend() { 949 return switch_state(SR_RUNNING, SR_SUSPEND_REQUEST); 950 } 951 952 State cancel_suspend() { 953 return switch_state(SR_SUSPEND_REQUEST, SR_RUNNING); 954 } 955 956 State suspended() { 957 return switch_state(SR_SUSPEND_REQUEST, SR_SUSPENDED); 958 } 959 960 State request_wakeup() { 961 return switch_state(SR_SUSPENDED, SR_WAKEUP_REQUEST); 962 } 963 964 State running() { 965 return switch_state(SR_WAKEUP_REQUEST, SR_RUNNING); 966 } 967 968 bool is_running() const { 969 return _state == SR_RUNNING; 970 } 971 972 bool is_suspend_request() const { 973 return _state == SR_SUSPEND_REQUEST; 974 } 975 976 bool is_suspended() const { 977 return _state == SR_SUSPENDED; 978 } 979 }; 980#endif 981 982 983 protected: 984 static long _rand_seed; // seed for random number generator 985 static int _processor_count; // number of processors 986 987 static char* format_boot_path(const char* format_string, 988 const char* home, 989 int home_len, 990 char fileSep, 991 char pathSep); 992 static bool set_boot_path(char fileSep, char pathSep); 993 static char** split_path(const char* path, int* n); 994 995}; 996 997// Note that "PAUSE" is almost always used with synchronization 998// so arguably we should provide Atomic::SpinPause() instead 999// of the global SpinPause() with C linkage. 1000// It'd also be eligible for inlining on many platforms. 1001 1002extern "C" int SpinPause(); 1003 1004#endif // SHARE_VM_RUNTIME_OS_HPP 1005