1 /* 2 * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef OS_WINDOWS_OS_WINDOWS_HPP 26 #define OS_WINDOWS_OS_WINDOWS_HPP 27 // Win32_OS defines the interface to windows operating systems 28 29 // strtok_s is the Windows thread-safe equivalent of POSIX strtok_r 30 #define strtok_r strtok_s 31 32 #define S_ISCHR(mode) (((mode) & _S_IFCHR) == _S_IFCHR) 33 #define S_ISFIFO(mode) (((mode) & _S_IFIFO) == _S_IFIFO) 34 35 // Information about the protection of the page at address '0' on this os. 36 static bool zero_page_read_protected() { return true; } 37 38 // File conventions 39 static const char* file_separator() { return "\\"; } 40 static const char* line_separator() { return "\r\n"; } 41 static const char* path_separator() { return ";"; } 42 43 class win32 { 44 friend class os; 45 friend unsigned __stdcall thread_native_entry(class Thread*); 46 47 protected: 48 static int _vm_page_size; 49 static int _vm_allocation_granularity; 50 static int _processor_type; 51 static int _processor_level; 52 static julong _physical_memory; 53 static size_t _default_stack_size; 54 static bool _is_windows_server; 55 static bool _has_exit_bug; 56 57 static void print_windows_version(outputStream* st); 58 static void print_uptime_info(outputStream* st); 59 60 public: 61 // Windows-specific interface: 62 static void initialize_system_info(); 63 static void setmode_streams(); 64 65 // Processor info as provided by NT 66 static int processor_type() { return _processor_type; } 67 static int processor_level() { 68 return _processor_level; 69 } 70 static julong available_memory(); 71 static julong physical_memory() { return _physical_memory; } 72 73 // load dll from Windows system directory or Windows directory 74 static HINSTANCE load_Windows_dll(const char* name, char *ebuf, int ebuflen); 75 76 private: 77 enum Ept { EPT_THREAD, EPT_PROCESS, EPT_PROCESS_DIE }; 78 // Wrapper around _endthreadex(), exit() and _exit() 79 static int exit_process_or_thread(Ept what, int exit_code); 80 81 static void initialize_performance_counter(); 82 83 public: 84 // Generic interface: 85 86 // Trace number of created threads 87 static intx _os_thread_limit; 88 static volatile intx _os_thread_count; 89 90 // Tells whether this is a server version of Windows 91 static bool is_windows_server() { return _is_windows_server; } 92 93 // Tells whether there can be the race bug during process exit on this platform 94 static bool has_exit_bug() { return _has_exit_bug; } 95 96 // Returns the byte size of a virtual memory page 97 static int vm_page_size() { return _vm_page_size; } 98 99 // Returns the size in bytes of memory blocks which can be allocated. 100 static int vm_allocation_granularity() { return _vm_allocation_granularity; } 101 102 // Read the headers for the executable that started the current process into 103 // the structure passed in (see winnt.h). 104 static void read_executable_headers(PIMAGE_NT_HEADERS); 105 106 // Default stack size for the current process. 107 static size_t default_stack_size() { return _default_stack_size; } 108 109 static bool get_frame_at_stack_banging_point(JavaThread* thread, 110 struct _EXCEPTION_POINTERS* exceptionInfo, 111 address pc, frame* fr); 112 113 #ifndef _WIN64 114 // A wrapper to install a structured exception handler for fast JNI accesors. 115 static address fast_jni_accessor_wrapper(BasicType); 116 #endif 117 118 // Fast access to current thread 119 protected: 120 static int _thread_ptr_offset; 121 private: 122 static void initialize_thread_ptr_offset(); 123 public: 124 static inline void set_thread_ptr_offset(int offset) { 125 _thread_ptr_offset = offset; 126 } 127 static inline int get_thread_ptr_offset() { return _thread_ptr_offset; } 128 }; 129 130 /* 131 * Crash protection for the watcher thread. Wrap the callback 132 * with a __try { call() } 133 * To be able to use this - don't take locks, don't rely on destructors, 134 * don't make OS library calls, don't allocate memory, don't print, 135 * don't call code that could leave the heap / memory in an inconsistent state, 136 * or anything else where we are not in control if we suddenly jump out. 137 */ 138 class ThreadCrashProtection : public StackObj { 139 public: 140 static bool is_crash_protected(Thread* thr) { 141 return _crash_protection != NULL && _protected_thread == thr; 142 } 143 144 ThreadCrashProtection(); 145 bool call(os::CrashProtectionCallback& cb); 146 private: 147 static Thread* _protected_thread; 148 static ThreadCrashProtection* _crash_protection; 149 static volatile intptr_t _crash_mux; 150 }; 151 152 class PlatformEvent : public CHeapObj<mtSynchronizer> { 153 private: 154 double CachePad [4] ; // increase odds that _Event is sole occupant of cache line 155 volatile int _Event ; 156 HANDLE _ParkHandle ; 157 158 public: // TODO-FIXME: make dtor private 159 ~PlatformEvent() { guarantee (0, "invariant") ; } 160 161 public: 162 PlatformEvent() { 163 _Event = 0 ; 164 _ParkHandle = CreateEvent (NULL, false, false, NULL) ; 165 guarantee (_ParkHandle != NULL, "invariant") ; 166 } 167 168 // Exercise caution using reset() and fired() - they may require MEMBARs 169 void reset() { _Event = 0 ; } 170 int fired() { return _Event; } 171 void park () ; 172 void unpark () ; 173 int park (jlong millis) ; 174 } ; 175 176 177 178 class PlatformParker : public CHeapObj<mtSynchronizer> { 179 protected: 180 HANDLE _ParkEvent ; 181 182 public: 183 ~PlatformParker () { guarantee (0, "invariant") ; } 184 PlatformParker () { 185 _ParkEvent = CreateEvent (NULL, true, false, NULL) ; 186 guarantee (_ParkEvent != NULL, "invariant") ; 187 } 188 189 } ; 190 191 // Platform specific implementations that underpin VM Mutex/Monitor classes 192 193 class PlatformMutex : public CHeapObj<mtSynchronizer> { 194 NONCOPYABLE(PlatformMutex); 195 196 protected: 197 CRITICAL_SECTION _mutex; // Native mutex for locking 198 199 public: 200 PlatformMutex(); 201 ~PlatformMutex(); 202 void lock(); 203 void unlock(); 204 bool try_lock(); 205 }; 206 207 class PlatformMonitor : public PlatformMutex { 208 private: 209 CONDITION_VARIABLE _cond; // Native condition variable for blocking 210 NONCOPYABLE(PlatformMonitor); 211 212 public: 213 PlatformMonitor(); 214 ~PlatformMonitor(); 215 int wait(jlong millis); 216 void notify(); 217 void notify_all(); 218 }; 219 220 #endif // OS_WINDOWS_OS_WINDOWS_HPP