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 59 public: 60 // Windows-specific interface: 61 static void initialize_system_info(); 62 static void setmode_streams(); 63 64 // Processor info as provided by NT 65 static int processor_type() { return _processor_type; } 66 static int processor_level() { 67 return _processor_level; 68 } 69 static julong available_memory(); 70 static julong physical_memory() { return _physical_memory; } 71 72 // load dll from Windows system directory or Windows directory 73 static HINSTANCE load_Windows_dll(const char* name, char *ebuf, int ebuflen); 74 75 private: 76 enum Ept { EPT_THREAD, EPT_PROCESS, EPT_PROCESS_DIE }; 77 // Wrapper around _endthreadex(), exit() and _exit() 78 static int exit_process_or_thread(Ept what, int exit_code); 79 80 static void initialize_performance_counter(); 81 82 public: 83 // Generic interface: 84 85 // Trace number of created threads 86 static intx _os_thread_limit; 87 static volatile intx _os_thread_count; 88 89 // Tells whether this is a server version of Windows 90 static bool is_windows_server() { return _is_windows_server; } 91 92 // Tells whether there can be the race bug during process exit on this platform 93 static bool has_exit_bug() { return _has_exit_bug; } 94 95 // Returns the byte size of a virtual memory page 96 static int vm_page_size() { return _vm_page_size; } 97 98 // Returns the size in bytes of memory blocks which can be allocated. 99 static int vm_allocation_granularity() { return _vm_allocation_granularity; } 100 101 // Read the headers for the executable that started the current process into 102 // the structure passed in (see winnt.h). 103 static void read_executable_headers(PIMAGE_NT_HEADERS); 104 105 // Default stack size for the current process. 106 static size_t default_stack_size() { return _default_stack_size; } 107 108 static bool get_frame_at_stack_banging_point(JavaThread* thread, 109 struct _EXCEPTION_POINTERS* exceptionInfo, 110 address pc, frame* fr); 111 112 #ifndef _WIN64 113 // A wrapper to install a structured exception handler for fast JNI accesors. 114 static address fast_jni_accessor_wrapper(BasicType); 115 #endif 116 117 // Fast access to current thread 118 protected: 119 static int _thread_ptr_offset; 120 private: 121 static void initialize_thread_ptr_offset(); 122 public: 123 static inline void set_thread_ptr_offset(int offset) { 124 _thread_ptr_offset = offset; 125 } 126 static inline int get_thread_ptr_offset() { return _thread_ptr_offset; } 127 }; 128 129 /* 130 * Crash protection for the watcher thread. Wrap the callback 131 * with a __try { call() } 132 * To be able to use this - don't take locks, don't rely on destructors, 133 * don't make OS library calls, don't allocate memory, don't print, 134 * don't call code that could leave the heap / memory in an inconsistent state, 135 * or anything else where we are not in control if we suddenly jump out. 136 */ 137 class ThreadCrashProtection : public StackObj { 138 public: 139 static bool is_crash_protected(Thread* thr) { 140 return _crash_protection != NULL && _protected_thread == thr; 141 } 142 143 ThreadCrashProtection(); 144 bool call(os::CrashProtectionCallback& cb); 145 private: 146 static Thread* _protected_thread; 147 static ThreadCrashProtection* _crash_protection; 148 static volatile intptr_t _crash_mux; 149 }; 150 151 class PlatformEvent : public CHeapObj<mtSynchronizer> { 152 private: 153 double CachePad [4] ; // increase odds that _Event is sole occupant of cache line 154 volatile int _Event ; 155 HANDLE _ParkHandle ; 156 157 public: // TODO-FIXME: make dtor private 158 ~PlatformEvent() { guarantee (0, "invariant") ; } 159 160 public: 161 PlatformEvent() { 162 _Event = 0 ; 163 _ParkHandle = CreateEvent (NULL, false, false, NULL) ; 164 guarantee (_ParkHandle != NULL, "invariant") ; 165 } 166 167 // Exercise caution using reset() and fired() - they may require MEMBARs 168 void reset() { _Event = 0 ; } 169 int fired() { return _Event; } 170 void park () ; 171 void unpark () ; 172 int park (jlong millis) ; 173 } ; 174 175 176 177 class PlatformParker : public CHeapObj<mtSynchronizer> { 178 protected: 179 HANDLE _ParkEvent ; 180 181 public: 182 ~PlatformParker () { guarantee (0, "invariant") ; } 183 PlatformParker () { 184 _ParkEvent = CreateEvent (NULL, true, false, NULL) ; 185 guarantee (_ParkEvent != NULL, "invariant") ; 186 } 187 188 } ; 189 190 // Platform specific implementations that underpin VM Mutex/Monitor classes 191 192 class PlatformMutex : public CHeapObj<mtSynchronizer> { 193 // Disable copying 194 PlatformMutex(const PlatformMutex&); 195 PlatformMutex& operator=(const PlatformMutex&); 196 197 protected: 198 CRITICAL_SECTION _mutex; // Native mutex for locking 199 200 public: 201 PlatformMutex(); 202 ~PlatformMutex(); 203 void lock(); 204 void unlock(); 205 bool try_lock(); 206 }; 207 208 class PlatformMonitor : public PlatformMutex { 209 private: 210 CONDITION_VARIABLE _cond; // Native condition variable for blocking 211 // Disable copying 212 PlatformMonitor(const PlatformMonitor&); 213 PlatformMonitor& operator=(const PlatformMonitor&); 214 215 public: 216 PlatformMonitor(); 217 ~PlatformMonitor(); 218 int wait(jlong millis); 219 void notify(); 220 void notify_all(); 221 }; 222 223 #endif // OS_WINDOWS_OS_WINDOWS_HPP