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