1// Copyright 2009 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package runtime
6
7import (
8	"internal/abi"
9	"internal/goarch"
10	"runtime/internal/atomic"
11	"unsafe"
12)
13
14// TODO(brainman): should not need those
15const (
16	_NSIG = 65
17)
18
19//go:cgo_import_dynamic runtime._AddVectoredExceptionHandler AddVectoredExceptionHandler%2 "kernel32.dll"
20//go:cgo_import_dynamic runtime._CloseHandle CloseHandle%1 "kernel32.dll"
21//go:cgo_import_dynamic runtime._CreateEventA CreateEventA%4 "kernel32.dll"
22//go:cgo_import_dynamic runtime._CreateFileA CreateFileA%7 "kernel32.dll"
23//go:cgo_import_dynamic runtime._CreateIoCompletionPort CreateIoCompletionPort%4 "kernel32.dll"
24//go:cgo_import_dynamic runtime._CreateThread CreateThread%6 "kernel32.dll"
25//go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA%3 "kernel32.dll"
26//go:cgo_import_dynamic runtime._CreateWaitableTimerExW CreateWaitableTimerExW%4 "kernel32.dll"
27//go:cgo_import_dynamic runtime._DuplicateHandle DuplicateHandle%7 "kernel32.dll"
28//go:cgo_import_dynamic runtime._ExitProcess ExitProcess%1 "kernel32.dll"
29//go:cgo_import_dynamic runtime._FreeEnvironmentStringsW FreeEnvironmentStringsW%1 "kernel32.dll"
30//go:cgo_import_dynamic runtime._GetConsoleMode GetConsoleMode%2 "kernel32.dll"
31//go:cgo_import_dynamic runtime._GetEnvironmentStringsW GetEnvironmentStringsW%0 "kernel32.dll"
32//go:cgo_import_dynamic runtime._GetProcAddress GetProcAddress%2 "kernel32.dll"
33//go:cgo_import_dynamic runtime._GetProcessAffinityMask GetProcessAffinityMask%3 "kernel32.dll"
34//go:cgo_import_dynamic runtime._GetQueuedCompletionStatusEx GetQueuedCompletionStatusEx%6 "kernel32.dll"
35//go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle%1 "kernel32.dll"
36//go:cgo_import_dynamic runtime._GetSystemDirectoryA GetSystemDirectoryA%2 "kernel32.dll"
37//go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll"
38//go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll"
39//go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll"
40//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll"
41//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll"
42//go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll"
43//go:cgo_import_dynamic runtime._ResumeThread ResumeThread%1 "kernel32.dll"
44//go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler%2 "kernel32.dll"
45//go:cgo_import_dynamic runtime._SetErrorMode SetErrorMode%1 "kernel32.dll"
46//go:cgo_import_dynamic runtime._SetEvent SetEvent%1 "kernel32.dll"
47//go:cgo_import_dynamic runtime._SetProcessPriorityBoost SetProcessPriorityBoost%2 "kernel32.dll"
48//go:cgo_import_dynamic runtime._SetThreadPriority SetThreadPriority%2 "kernel32.dll"
49//go:cgo_import_dynamic runtime._SetUnhandledExceptionFilter SetUnhandledExceptionFilter%1 "kernel32.dll"
50//go:cgo_import_dynamic runtime._SetWaitableTimer SetWaitableTimer%6 "kernel32.dll"
51//go:cgo_import_dynamic runtime._Sleep Sleep%1 "kernel32.dll"
52//go:cgo_import_dynamic runtime._SuspendThread SuspendThread%1 "kernel32.dll"
53//go:cgo_import_dynamic runtime._SwitchToThread SwitchToThread%0 "kernel32.dll"
54//go:cgo_import_dynamic runtime._TlsAlloc TlsAlloc%0 "kernel32.dll"
55//go:cgo_import_dynamic runtime._VirtualAlloc VirtualAlloc%4 "kernel32.dll"
56//go:cgo_import_dynamic runtime._VirtualFree VirtualFree%3 "kernel32.dll"
57//go:cgo_import_dynamic runtime._VirtualQuery VirtualQuery%3 "kernel32.dll"
58//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll"
59//go:cgo_import_dynamic runtime._WaitForMultipleObjects WaitForMultipleObjects%4 "kernel32.dll"
60//go:cgo_import_dynamic runtime._WriteConsoleW WriteConsoleW%5 "kernel32.dll"
61//go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll"
62
63type stdFunction unsafe.Pointer
64
65var (
66	// Following syscalls are available on every Windows PC.
67	// All these variables are set by the Windows executable
68	// loader before the Go program starts.
69	_AddVectoredExceptionHandler,
70	_CloseHandle,
71	_CreateEventA,
72	_CreateFileA,
73	_CreateIoCompletionPort,
74	_CreateThread,
75	_CreateWaitableTimerA,
76	_CreateWaitableTimerExW,
77	_DuplicateHandle,
78	_ExitProcess,
79	_FreeEnvironmentStringsW,
80	_GetConsoleMode,
81	_GetEnvironmentStringsW,
82	_GetProcAddress,
83	_GetProcessAffinityMask,
84	_GetQueuedCompletionStatusEx,
85	_GetStdHandle,
86	_GetSystemDirectoryA,
87	_GetSystemInfo,
88	_GetSystemTimeAsFileTime,
89	_GetThreadContext,
90	_SetThreadContext,
91	_LoadLibraryW,
92	_LoadLibraryA,
93	_PostQueuedCompletionStatus,
94	_QueryPerformanceCounter,
95	_QueryPerformanceFrequency,
96	_ResumeThread,
97	_SetConsoleCtrlHandler,
98	_SetErrorMode,
99	_SetEvent,
100	_SetProcessPriorityBoost,
101	_SetThreadPriority,
102	_SetUnhandledExceptionFilter,
103	_SetWaitableTimer,
104	_Sleep,
105	_SuspendThread,
106	_SwitchToThread,
107	_TlsAlloc,
108	_VirtualAlloc,
109	_VirtualFree,
110	_VirtualQuery,
111	_WaitForSingleObject,
112	_WaitForMultipleObjects,
113	_WriteConsoleW,
114	_WriteFile,
115	_ stdFunction
116
117	// Following syscalls are only available on some Windows PCs.
118	// We will load syscalls, if available, before using them.
119	_AddDllDirectory,
120	_AddVectoredContinueHandler,
121	_LoadLibraryExA,
122	_LoadLibraryExW,
123	_ stdFunction
124
125	// Use RtlGenRandom to generate cryptographically random data.
126	// This approach has been recommended by Microsoft (see issue
127	// 15589 for details).
128	// The RtlGenRandom is not listed in advapi32.dll, instead
129	// RtlGenRandom function can be found by searching for SystemFunction036.
130	// Also some versions of Mingw cannot link to SystemFunction036
131	// when building executable as Cgo. So load SystemFunction036
132	// manually during runtime startup.
133	_RtlGenRandom stdFunction
134
135	// Load ntdll.dll manually during startup, otherwise Mingw
136	// links wrong printf function to cgo executable (see issue
137	// 12030 for details).
138	_NtWaitForSingleObject  stdFunction
139	_RtlGetCurrentPeb       stdFunction
140	_RtlGetNtVersionNumbers stdFunction
141
142	// These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
143	_timeBeginPeriod,
144	_timeEndPeriod,
145	_WSAGetOverlappedResult,
146	_ stdFunction
147)
148
149// Function to be called by windows CreateThread
150// to start new os thread.
151func tstart_stdcall(newm *m)
152
153// Init-time helper
154func wintls()
155
156type mOS struct {
157	threadLock mutex   // protects "thread" and prevents closing
158	thread     uintptr // thread handle
159
160	waitsema   uintptr // semaphore for parking on locks
161	resumesema uintptr // semaphore to indicate suspend/resume
162
163	highResTimer uintptr // high resolution timer handle used in usleep
164
165	// preemptExtLock synchronizes preemptM with entry/exit from
166	// external C code.
167	//
168	// This protects against races between preemptM calling
169	// SuspendThread and external code on this thread calling
170	// ExitProcess. If these happen concurrently, it's possible to
171	// exit the suspending thread and suspend the exiting thread,
172	// leading to deadlock.
173	//
174	// 0 indicates this M is not being preempted or in external
175	// code. Entering external code CASes this from 0 to 1. If
176	// this fails, a preemption is in progress, so the thread must
177	// wait for the preemption. preemptM also CASes this from 0 to
178	// 1. If this fails, the preemption fails (as it would if the
179	// PC weren't in Go code). The value is reset to 0 when
180	// returning from external code or after a preemption is
181	// complete.
182	//
183	// TODO(austin): We may not need this if preemption were more
184	// tightly synchronized on the G/P status and preemption
185	// blocked transition into _Gsyscall/_Psyscall.
186	preemptExtLock uint32
187}
188
189//go:linkname os_sigpipe os.sigpipe
190func os_sigpipe() {
191	throw("too many writes on closed pipe")
192}
193
194// Stubs so tests can link correctly. These should never be called.
195func open(name *byte, mode, perm int32) int32 {
196	throw("unimplemented")
197	return -1
198}
199func closefd(fd int32) int32 {
200	throw("unimplemented")
201	return -1
202}
203func read(fd int32, p unsafe.Pointer, n int32) int32 {
204	throw("unimplemented")
205	return -1
206}
207
208type sigset struct{}
209
210// Call a Windows function with stdcall conventions,
211// and switch to os stack during the call.
212func asmstdcall(fn unsafe.Pointer)
213
214var asmstdcallAddr unsafe.Pointer
215
216func windowsFindfunc(lib uintptr, name []byte) stdFunction {
217	if name[len(name)-1] != 0 {
218		throw("usage")
219	}
220	f := stdcall2(_GetProcAddress, lib, uintptr(unsafe.Pointer(&name[0])))
221	return stdFunction(unsafe.Pointer(f))
222}
223
224const _MAX_PATH = 260 // https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation
225var sysDirectory [_MAX_PATH + 1]byte
226var sysDirectoryLen uintptr
227
228func windowsLoadSystemLib(name []byte) uintptr {
229	if sysDirectoryLen == 0 {
230		l := stdcall2(_GetSystemDirectoryA, uintptr(unsafe.Pointer(&sysDirectory[0])), uintptr(len(sysDirectory)-1))
231		if l == 0 || l > uintptr(len(sysDirectory)-1) {
232			throw("Unable to determine system directory")
233		}
234		sysDirectory[l] = '\\'
235		sysDirectoryLen = l + 1
236	}
237	if useLoadLibraryEx {
238		return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32)
239	} else {
240		absName := append(sysDirectory[:sysDirectoryLen], name...)
241		return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0])))
242	}
243}
244
245const haveCputicksAsm = GOARCH == "386" || GOARCH == "amd64"
246
247func loadOptionalSyscalls() {
248	var kernel32dll = []byte("kernel32.dll\000")
249	k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0])))
250	if k32 == 0 {
251		throw("kernel32.dll not found")
252	}
253	_AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000"))
254	_AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000"))
255	_LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000"))
256	_LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000"))
257	useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil)
258
259	var advapi32dll = []byte("advapi32.dll\000")
260	a32 := windowsLoadSystemLib(advapi32dll)
261	if a32 == 0 {
262		throw("advapi32.dll not found")
263	}
264	_RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))
265
266	var ntdll = []byte("ntdll.dll\000")
267	n32 := windowsLoadSystemLib(ntdll)
268	if n32 == 0 {
269		throw("ntdll.dll not found")
270	}
271	_NtWaitForSingleObject = windowsFindfunc(n32, []byte("NtWaitForSingleObject\000"))
272	_RtlGetCurrentPeb = windowsFindfunc(n32, []byte("RtlGetCurrentPeb\000"))
273	_RtlGetNtVersionNumbers = windowsFindfunc(n32, []byte("RtlGetNtVersionNumbers\000"))
274
275	if !haveCputicksAsm {
276		_QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
277		if _QueryPerformanceCounter == nil {
278			throw("could not find QPC syscalls")
279		}
280	}
281
282	var winmmdll = []byte("winmm.dll\000")
283	m32 := windowsLoadSystemLib(winmmdll)
284	if m32 == 0 {
285		throw("winmm.dll not found")
286	}
287	_timeBeginPeriod = windowsFindfunc(m32, []byte("timeBeginPeriod\000"))
288	_timeEndPeriod = windowsFindfunc(m32, []byte("timeEndPeriod\000"))
289	if _timeBeginPeriod == nil || _timeEndPeriod == nil {
290		throw("timeBegin/EndPeriod not found")
291	}
292
293	var ws232dll = []byte("ws2_32.dll\000")
294	ws232 := windowsLoadSystemLib(ws232dll)
295	if ws232 == 0 {
296		throw("ws2_32.dll not found")
297	}
298	_WSAGetOverlappedResult = windowsFindfunc(ws232, []byte("WSAGetOverlappedResult\000"))
299	if _WSAGetOverlappedResult == nil {
300		throw("WSAGetOverlappedResult not found")
301	}
302
303	if windowsFindfunc(n32, []byte("wine_get_version\000")) != nil {
304		// running on Wine
305		initWine(k32)
306	}
307}
308
309func monitorSuspendResume() {
310	const (
311		_DEVICE_NOTIFY_CALLBACK = 2
312	)
313	type _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS struct {
314		callback uintptr
315		context  uintptr
316	}
317
318	powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000"))
319	if powrprof == 0 {
320		return // Running on Windows 7, where we don't need it anyway.
321	}
322	powerRegisterSuspendResumeNotification := windowsFindfunc(powrprof, []byte("PowerRegisterSuspendResumeNotification\000"))
323	if powerRegisterSuspendResumeNotification == nil {
324		return // Running on Windows 7, where we don't need it anyway.
325	}
326	var fn any = func(context uintptr, changeType uint32, setting uintptr) uintptr {
327		for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
328			if mp.resumesema != 0 {
329				stdcall1(_SetEvent, mp.resumesema)
330			}
331		}
332		return 0
333	}
334	params := _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS{
335		callback: compileCallback(*efaceOf(&fn), true),
336	}
337	handle := uintptr(0)
338	stdcall3(powerRegisterSuspendResumeNotification, _DEVICE_NOTIFY_CALLBACK,
339		uintptr(unsafe.Pointer(&params)), uintptr(unsafe.Pointer(&handle)))
340}
341
342//go:nosplit
343func getLoadLibrary() uintptr {
344	return uintptr(unsafe.Pointer(_LoadLibraryW))
345}
346
347//go:nosplit
348func getLoadLibraryEx() uintptr {
349	return uintptr(unsafe.Pointer(_LoadLibraryExW))
350}
351
352//go:nosplit
353func getGetProcAddress() uintptr {
354	return uintptr(unsafe.Pointer(_GetProcAddress))
355}
356
357func getproccount() int32 {
358	var mask, sysmask uintptr
359	ret := stdcall3(_GetProcessAffinityMask, currentProcess, uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask)))
360	if ret != 0 {
361		n := 0
362		maskbits := int(unsafe.Sizeof(mask) * 8)
363		for i := 0; i < maskbits; i++ {
364			if mask&(1<<uint(i)) != 0 {
365				n++
366			}
367		}
368		if n != 0 {
369			return int32(n)
370		}
371	}
372	// use GetSystemInfo if GetProcessAffinityMask fails
373	var info systeminfo
374	stdcall1(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
375	return int32(info.dwnumberofprocessors)
376}
377
378func getPageSize() uintptr {
379	var info systeminfo
380	stdcall1(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
381	return uintptr(info.dwpagesize)
382}
383
384const (
385	currentProcess = ^uintptr(0) // -1 = current process
386	currentThread  = ^uintptr(1) // -2 = current thread
387)
388
389// in sys_windows_386.s and sys_windows_amd64.s:
390func getlasterror() uint32
391
392// When loading DLLs, we prefer to use LoadLibraryEx with
393// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not
394// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_*
395// flags are not available on some versions of Windows without a
396// security patch.
397//
398// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says:
399// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows
400// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on
401// systems that have KB2533623 installed. To determine whether the
402// flags are available, use GetProcAddress to get the address of the
403// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories
404// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_*
405// flags can be used with LoadLibraryEx."
406var useLoadLibraryEx bool
407
408var timeBeginPeriodRetValue uint32
409
410// osRelaxMinNS indicates that sysmon shouldn't osRelax if the next
411// timer is less than 60 ms from now. Since osRelaxing may reduce
412// timer resolution to 15.6 ms, this keeps timer error under roughly 1
413// part in 4.
414const osRelaxMinNS = 60 * 1e6
415
416// osRelax is called by the scheduler when transitioning to and from
417// all Ps being idle.
418//
419// Some versions of Windows have high resolution timer. For those
420// versions osRelax is noop.
421// For Windows versions without high resolution timer, osRelax
422// adjusts the system-wide timer resolution. Go needs a
423// high resolution timer while running and there's little extra cost
424// if we're already using the CPU, but if all Ps are idle there's no
425// need to consume extra power to drive the high-res timer.
426func osRelax(relax bool) uint32 {
427	if haveHighResTimer {
428		// If the high resolution timer is available, the runtime uses the timer
429		// to sleep for short durations. This means there's no need to adjust
430		// the global clock frequency.
431		return 0
432	}
433
434	if relax {
435		return uint32(stdcall1(_timeEndPeriod, 1))
436	} else {
437		return uint32(stdcall1(_timeBeginPeriod, 1))
438	}
439}
440
441// haveHighResTimer indicates that the CreateWaitableTimerEx
442// CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag is available.
443var haveHighResTimer = false
444
445// createHighResTimer calls CreateWaitableTimerEx with
446// CREATE_WAITABLE_TIMER_HIGH_RESOLUTION flag to create high
447// resolution timer. createHighResTimer returns new timer
448// handle or 0, if CreateWaitableTimerEx failed.
449func createHighResTimer() uintptr {
450	const (
451		// As per @jstarks, see
452		// https://github.com/golang/go/issues/8687#issuecomment-656259353
453		_CREATE_WAITABLE_TIMER_HIGH_RESOLUTION = 0x00000002
454
455		_SYNCHRONIZE        = 0x00100000
456		_TIMER_QUERY_STATE  = 0x0001
457		_TIMER_MODIFY_STATE = 0x0002
458	)
459	return stdcall4(_CreateWaitableTimerExW, 0, 0,
460		_CREATE_WAITABLE_TIMER_HIGH_RESOLUTION,
461		_SYNCHRONIZE|_TIMER_QUERY_STATE|_TIMER_MODIFY_STATE)
462}
463
464const highResTimerSupported = GOARCH == "386" || GOARCH == "amd64"
465
466func initHighResTimer() {
467	if !highResTimerSupported {
468		// TODO: Not yet implemented.
469		return
470	}
471	h := createHighResTimer()
472	if h != 0 {
473		haveHighResTimer = true
474		stdcall1(_CloseHandle, h)
475	}
476}
477
478//go:linkname canUseLongPaths os.canUseLongPaths
479var canUseLongPaths bool
480
481// We want this to be large enough to hold the contents of sysDirectory, *plus*
482// a slash and another component that itself is greater than MAX_PATH.
483var longFileName [(_MAX_PATH+1)*2 + 1]byte
484
485// initLongPathSupport initializes the canUseLongPaths variable, which is
486// linked into os.canUseLongPaths for determining whether or not long paths
487// need to be fixed up. In the best case, this function is running on newer
488// Windows 10 builds, which have a bit field member of the PEB called
489// "IsLongPathAwareProcess." When this is set, we don't need to go through the
490// error-prone fixup function in order to access long paths. So this init
491// function first checks the Windows build number, sets the flag, and then
492// tests to see if it's actually working. If everything checks out, then
493// canUseLongPaths is set to true, and later when called, os.fixLongPath
494// returns early without doing work.
495func initLongPathSupport() {
496	const (
497		IsLongPathAwareProcess = 0x80
498		PebBitFieldOffset      = 3
499		OPEN_EXISTING          = 3
500		ERROR_PATH_NOT_FOUND   = 3
501	)
502
503	// Check that we're ≥ 10.0.15063.
504	var maj, min, build uint32
505	stdcall3(_RtlGetNtVersionNumbers, uintptr(unsafe.Pointer(&maj)), uintptr(unsafe.Pointer(&min)), uintptr(unsafe.Pointer(&build)))
506	if maj < 10 || (maj == 10 && min == 0 && build&0xffff < 15063) {
507		return
508	}
509
510	// Set the IsLongPathAwareProcess flag of the PEB's bit field.
511	bitField := (*byte)(unsafe.Pointer(stdcall0(_RtlGetCurrentPeb) + PebBitFieldOffset))
512	originalBitField := *bitField
513	*bitField |= IsLongPathAwareProcess
514
515	// Check that this actually has an effect, by constructing a large file
516	// path and seeing whether we get ERROR_PATH_NOT_FOUND, rather than
517	// some other error, which would indicate the path is too long, and
518	// hence long path support is not successful. This whole section is NOT
519	// strictly necessary, but is a nice validity check for the near to
520	// medium term, when this functionality is still relatively new in
521	// Windows.
522	getRandomData(longFileName[len(longFileName)-33 : len(longFileName)-1])
523	start := copy(longFileName[:], sysDirectory[:sysDirectoryLen])
524	const dig = "0123456789abcdef"
525	for i := 0; i < 32; i++ {
526		longFileName[start+i*2] = dig[longFileName[len(longFileName)-33+i]>>4]
527		longFileName[start+i*2+1] = dig[longFileName[len(longFileName)-33+i]&0xf]
528	}
529	start += 64
530	for i := start; i < len(longFileName)-1; i++ {
531		longFileName[i] = 'A'
532	}
533	stdcall7(_CreateFileA, uintptr(unsafe.Pointer(&longFileName[0])), 0, 0, 0, OPEN_EXISTING, 0, 0)
534	// The ERROR_PATH_NOT_FOUND error value is distinct from
535	// ERROR_FILE_NOT_FOUND or ERROR_INVALID_NAME, the latter of which we
536	// expect here due to the final component being too long.
537	if getlasterror() == ERROR_PATH_NOT_FOUND {
538		*bitField = originalBitField
539		println("runtime: warning: IsLongPathAwareProcess failed to enable long paths; proceeding in fixup mode")
540		return
541	}
542
543	canUseLongPaths = true
544}
545
546func osinit() {
547	asmstdcallAddr = unsafe.Pointer(abi.FuncPCABI0(asmstdcall))
548
549	setBadSignalMsg()
550
551	loadOptionalSyscalls()
552
553	disableWER()
554
555	initExceptionHandler()
556
557	initHighResTimer()
558	timeBeginPeriodRetValue = osRelax(false)
559
560	initLongPathSupport()
561
562	ncpu = getproccount()
563
564	physPageSize = getPageSize()
565
566	// Windows dynamic priority boosting assumes that a process has different types
567	// of dedicated threads -- GUI, IO, computational, etc. Go processes use
568	// equivalent threads that all do a mix of GUI, IO, computations, etc.
569	// In such context dynamic priority boosting does nothing but harm, so we turn it off.
570	stdcall2(_SetProcessPriorityBoost, currentProcess, 1)
571}
572
573// useQPCTime controls whether time.now and nanotime use QueryPerformanceCounter.
574// This is only set to 1 when running under Wine.
575var useQPCTime uint8
576
577var qpcStartCounter int64
578var qpcMultiplier int64
579
580//go:nosplit
581func nanotimeQPC() int64 {
582	var counter int64 = 0
583	stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&counter)))
584
585	// returns number of nanoseconds
586	return (counter - qpcStartCounter) * qpcMultiplier
587}
588
589//go:nosplit
590func nowQPC() (sec int64, nsec int32, mono int64) {
591	var ft int64
592	stdcall1(_GetSystemTimeAsFileTime, uintptr(unsafe.Pointer(&ft)))
593
594	t := (ft - 116444736000000000) * 100
595
596	sec = t / 1000000000
597	nsec = int32(t - sec*1000000000)
598
599	mono = nanotimeQPC()
600	return
601}
602
603func initWine(k32 uintptr) {
604	_GetSystemTimeAsFileTime = windowsFindfunc(k32, []byte("GetSystemTimeAsFileTime\000"))
605	if _GetSystemTimeAsFileTime == nil {
606		throw("could not find GetSystemTimeAsFileTime() syscall")
607	}
608
609	_QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
610	_QueryPerformanceFrequency = windowsFindfunc(k32, []byte("QueryPerformanceFrequency\000"))
611	if _QueryPerformanceCounter == nil || _QueryPerformanceFrequency == nil {
612		throw("could not find QPC syscalls")
613	}
614
615	// We can not simply fallback to GetSystemTimeAsFileTime() syscall, since its time is not monotonic,
616	// instead we use QueryPerformanceCounter family of syscalls to implement monotonic timer
617	// https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
618
619	var tmp int64
620	stdcall1(_QueryPerformanceFrequency, uintptr(unsafe.Pointer(&tmp)))
621	if tmp == 0 {
622		throw("QueryPerformanceFrequency syscall returned zero, running on unsupported hardware")
623	}
624
625	// This should not overflow, it is a number of ticks of the performance counter per second,
626	// its resolution is at most 10 per usecond (on Wine, even smaller on real hardware), so it will be at most 10 millions here,
627	// panic if overflows.
628	if tmp > (1<<31 - 1) {
629		throw("QueryPerformanceFrequency overflow 32 bit divider, check nosplit discussion to proceed")
630	}
631	qpcFrequency := int32(tmp)
632	stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&qpcStartCounter)))
633
634	// Since we are supposed to run this time calls only on Wine, it does not lose precision,
635	// since Wine's timer is kind of emulated at 10 Mhz, so it will be a nice round multiplier of 100
636	// but for general purpose system (like 3.3 Mhz timer on i7) it will not be very precise.
637	// We have to do it this way (or similar), since multiplying QPC counter by 100 millions overflows
638	// int64 and resulted time will always be invalid.
639	qpcMultiplier = int64(timediv(1000000000, qpcFrequency, nil))
640
641	useQPCTime = 1
642}
643
644//go:nosplit
645func getRandomData(r []byte) {
646	n := 0
647	if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 {
648		n = len(r)
649	}
650	extendRandom(r, n)
651}
652
653func goenvs() {
654	// strings is a pointer to environment variable pairs in the form:
655	//     "envA=valA\x00envB=valB\x00\x00" (in UTF-16)
656	// Two consecutive zero bytes end the list.
657	strings := unsafe.Pointer(stdcall0(_GetEnvironmentStringsW))
658	p := (*[1 << 24]uint16)(strings)[:]
659
660	n := 0
661	for from, i := 0, 0; true; i++ {
662		if p[i] == 0 {
663			// empty string marks the end
664			if i == from {
665				break
666			}
667			from = i + 1
668			n++
669		}
670	}
671	envs = make([]string, n)
672
673	for i := range envs {
674		envs[i] = gostringw(&p[0])
675		for p[0] != 0 {
676			p = p[1:]
677		}
678		p = p[1:] // skip nil byte
679	}
680
681	stdcall1(_FreeEnvironmentStringsW, uintptr(strings))
682
683	// We call these all the way here, late in init, so that malloc works
684	// for the callback functions these generate.
685	var fn any = ctrlHandler
686	ctrlHandlerPC := compileCallback(*efaceOf(&fn), true)
687	stdcall2(_SetConsoleCtrlHandler, ctrlHandlerPC, 1)
688
689	monitorSuspendResume()
690}
691
692// exiting is set to non-zero when the process is exiting.
693var exiting uint32
694
695//go:nosplit
696func exit(code int32) {
697	// Disallow thread suspension for preemption. Otherwise,
698	// ExitProcess and SuspendThread can race: SuspendThread
699	// queues a suspension request for this thread, ExitProcess
700	// kills the suspending thread, and then this thread suspends.
701	lock(&suspendLock)
702	atomic.Store(&exiting, 1)
703	stdcall1(_ExitProcess, uintptr(code))
704}
705
706// write1 must be nosplit because it's used as a last resort in
707// functions like badmorestackg0. In such cases, we'll always take the
708// ASCII path.
709//
710//go:nosplit
711func write1(fd uintptr, buf unsafe.Pointer, n int32) int32 {
712	const (
713		_STD_OUTPUT_HANDLE = ^uintptr(10) // -11
714		_STD_ERROR_HANDLE  = ^uintptr(11) // -12
715	)
716	var handle uintptr
717	switch fd {
718	case 1:
719		handle = stdcall1(_GetStdHandle, _STD_OUTPUT_HANDLE)
720	case 2:
721		handle = stdcall1(_GetStdHandle, _STD_ERROR_HANDLE)
722	default:
723		// assume fd is real windows handle.
724		handle = fd
725	}
726	isASCII := true
727	b := (*[1 << 30]byte)(buf)[:n]
728	for _, x := range b {
729		if x >= 0x80 {
730			isASCII = false
731			break
732		}
733	}
734
735	if !isASCII {
736		var m uint32
737		isConsole := stdcall2(_GetConsoleMode, handle, uintptr(unsafe.Pointer(&m))) != 0
738		// If this is a console output, various non-unicode code pages can be in use.
739		// Use the dedicated WriteConsole call to ensure unicode is printed correctly.
740		if isConsole {
741			return int32(writeConsole(handle, buf, n))
742		}
743	}
744	var written uint32
745	stdcall5(_WriteFile, handle, uintptr(buf), uintptr(n), uintptr(unsafe.Pointer(&written)), 0)
746	return int32(written)
747}
748
749var (
750	utf16ConsoleBack     [1000]uint16
751	utf16ConsoleBackLock mutex
752)
753
754// writeConsole writes bufLen bytes from buf to the console File.
755// It returns the number of bytes written.
756func writeConsole(handle uintptr, buf unsafe.Pointer, bufLen int32) int {
757	const surr2 = (surrogateMin + surrogateMax + 1) / 2
758
759	// Do not use defer for unlock. May cause issues when printing a panic.
760	lock(&utf16ConsoleBackLock)
761
762	b := (*[1 << 30]byte)(buf)[:bufLen]
763	s := *(*string)(unsafe.Pointer(&b))
764
765	utf16tmp := utf16ConsoleBack[:]
766
767	total := len(s)
768	w := 0
769	for _, r := range s {
770		if w >= len(utf16tmp)-2 {
771			writeConsoleUTF16(handle, utf16tmp[:w])
772			w = 0
773		}
774		if r < 0x10000 {
775			utf16tmp[w] = uint16(r)
776			w++
777		} else {
778			r -= 0x10000
779			utf16tmp[w] = surrogateMin + uint16(r>>10)&0x3ff
780			utf16tmp[w+1] = surr2 + uint16(r)&0x3ff
781			w += 2
782		}
783	}
784	writeConsoleUTF16(handle, utf16tmp[:w])
785	unlock(&utf16ConsoleBackLock)
786	return total
787}
788
789// writeConsoleUTF16 is the dedicated windows calls that correctly prints
790// to the console regardless of the current code page. Input is utf-16 code points.
791// The handle must be a console handle.
792func writeConsoleUTF16(handle uintptr, b []uint16) {
793	l := uint32(len(b))
794	if l == 0 {
795		return
796	}
797	var written uint32
798	stdcall5(_WriteConsoleW,
799		handle,
800		uintptr(unsafe.Pointer(&b[0])),
801		uintptr(l),
802		uintptr(unsafe.Pointer(&written)),
803		0,
804	)
805	return
806}
807
808//go:nosplit
809func semasleep(ns int64) int32 {
810	const (
811		_WAIT_ABANDONED = 0x00000080
812		_WAIT_OBJECT_0  = 0x00000000
813		_WAIT_TIMEOUT   = 0x00000102
814		_WAIT_FAILED    = 0xFFFFFFFF
815	)
816
817	var result uintptr
818	if ns < 0 {
819		result = stdcall2(_WaitForSingleObject, getg().m.waitsema, uintptr(_INFINITE))
820	} else {
821		start := nanotime()
822		elapsed := int64(0)
823		for {
824			ms := int64(timediv(ns-elapsed, 1000000, nil))
825			if ms == 0 {
826				ms = 1
827			}
828			result = stdcall4(_WaitForMultipleObjects, 2,
829				uintptr(unsafe.Pointer(&[2]uintptr{getg().m.waitsema, getg().m.resumesema})),
830				0, uintptr(ms))
831			if result != _WAIT_OBJECT_0+1 {
832				// Not a suspend/resume event
833				break
834			}
835			elapsed = nanotime() - start
836			if elapsed >= ns {
837				return -1
838			}
839		}
840	}
841	switch result {
842	case _WAIT_OBJECT_0: // Signaled
843		return 0
844
845	case _WAIT_TIMEOUT:
846		return -1
847
848	case _WAIT_ABANDONED:
849		systemstack(func() {
850			throw("runtime.semasleep wait_abandoned")
851		})
852
853	case _WAIT_FAILED:
854		systemstack(func() {
855			print("runtime: waitforsingleobject wait_failed; errno=", getlasterror(), "\n")
856			throw("runtime.semasleep wait_failed")
857		})
858
859	default:
860		systemstack(func() {
861			print("runtime: waitforsingleobject unexpected; result=", result, "\n")
862			throw("runtime.semasleep unexpected")
863		})
864	}
865
866	return -1 // unreachable
867}
868
869//go:nosplit
870func semawakeup(mp *m) {
871	if stdcall1(_SetEvent, mp.waitsema) == 0 {
872		systemstack(func() {
873			print("runtime: setevent failed; errno=", getlasterror(), "\n")
874			throw("runtime.semawakeup")
875		})
876	}
877}
878
879//go:nosplit
880func semacreate(mp *m) {
881	if mp.waitsema != 0 {
882		return
883	}
884	mp.waitsema = stdcall4(_CreateEventA, 0, 0, 0, 0)
885	if mp.waitsema == 0 {
886		systemstack(func() {
887			print("runtime: createevent failed; errno=", getlasterror(), "\n")
888			throw("runtime.semacreate")
889		})
890	}
891	mp.resumesema = stdcall4(_CreateEventA, 0, 0, 0, 0)
892	if mp.resumesema == 0 {
893		systemstack(func() {
894			print("runtime: createevent failed; errno=", getlasterror(), "\n")
895			throw("runtime.semacreate")
896		})
897		stdcall1(_CloseHandle, mp.waitsema)
898		mp.waitsema = 0
899	}
900}
901
902// May run with m.p==nil, so write barriers are not allowed. This
903// function is called by newosproc0, so it is also required to
904// operate without stack guards.
905//go:nowritebarrierrec
906//go:nosplit
907func newosproc(mp *m) {
908	// We pass 0 for the stack size to use the default for this binary.
909	thandle := stdcall6(_CreateThread, 0, 0,
910		abi.FuncPCABI0(tstart_stdcall), uintptr(unsafe.Pointer(mp)),
911		0, 0)
912
913	if thandle == 0 {
914		if atomic.Load(&exiting) != 0 {
915			// CreateThread may fail if called
916			// concurrently with ExitProcess. If this
917			// happens, just freeze this thread and let
918			// the process exit. See issue #18253.
919			lock(&deadlock)
920			lock(&deadlock)
921		}
922		print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", getlasterror(), ")\n")
923		throw("runtime.newosproc")
924	}
925
926	// Close thandle to avoid leaking the thread object if it exits.
927	stdcall1(_CloseHandle, thandle)
928}
929
930// Used by the C library build mode. On Linux this function would allocate a
931// stack, but that's not necessary for Windows. No stack guards are present
932// and the GC has not been initialized, so write barriers will fail.
933//go:nowritebarrierrec
934//go:nosplit
935func newosproc0(mp *m, stk unsafe.Pointer) {
936	// TODO: this is completely broken. The args passed to newosproc0 (in asm_amd64.s)
937	// are stacksize and function, not *m and stack.
938	// Check os_linux.go for an implementation that might actually work.
939	throw("bad newosproc0")
940}
941
942func exitThread(wait *uint32) {
943	// We should never reach exitThread on Windows because we let
944	// the OS clean up threads.
945	throw("exitThread")
946}
947
948// Called to initialize a new m (including the bootstrap m).
949// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
950func mpreinit(mp *m) {
951}
952
953//go:nosplit
954func sigsave(p *sigset) {
955}
956
957//go:nosplit
958func msigrestore(sigmask sigset) {
959}
960
961//go:nosplit
962//go:nowritebarrierrec
963func clearSignalHandlers() {
964}
965
966//go:nosplit
967func sigblock(exiting bool) {
968}
969
970// Called to initialize a new m (including the bootstrap m).
971// Called on the new thread, cannot allocate memory.
972func minit() {
973	var thandle uintptr
974	if stdcall7(_DuplicateHandle, currentProcess, currentThread, currentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
975		print("runtime.minit: duplicatehandle failed; errno=", getlasterror(), "\n")
976		throw("runtime.minit: duplicatehandle failed")
977	}
978
979	mp := getg().m
980	lock(&mp.threadLock)
981	mp.thread = thandle
982
983	// Configure usleep timer, if possible.
984	if mp.highResTimer == 0 && haveHighResTimer {
985		mp.highResTimer = createHighResTimer()
986		if mp.highResTimer == 0 {
987			print("runtime: CreateWaitableTimerEx failed; errno=", getlasterror(), "\n")
988			throw("CreateWaitableTimerEx when creating timer failed")
989		}
990	}
991	unlock(&mp.threadLock)
992
993	// Query the true stack base from the OS. Currently we're
994	// running on a small assumed stack.
995	var mbi memoryBasicInformation
996	res := stdcall3(_VirtualQuery, uintptr(unsafe.Pointer(&mbi)), uintptr(unsafe.Pointer(&mbi)), unsafe.Sizeof(mbi))
997	if res == 0 {
998		print("runtime: VirtualQuery failed; errno=", getlasterror(), "\n")
999		throw("VirtualQuery for stack base failed")
1000	}
1001	// The system leaves an 8K PAGE_GUARD region at the bottom of
1002	// the stack (in theory VirtualQuery isn't supposed to include
1003	// that, but it does). Add an additional 8K of slop for
1004	// calling C functions that don't have stack checks and for
1005	// lastcontinuehandler. We shouldn't be anywhere near this
1006	// bound anyway.
1007	base := mbi.allocationBase + 16<<10
1008	// Sanity check the stack bounds.
1009	g0 := getg()
1010	if base > g0.stack.hi || g0.stack.hi-base > 64<<20 {
1011		print("runtime: g0 stack [", hex(base), ",", hex(g0.stack.hi), ")\n")
1012		throw("bad g0 stack")
1013	}
1014	g0.stack.lo = base
1015	g0.stackguard0 = g0.stack.lo + _StackGuard
1016	g0.stackguard1 = g0.stackguard0
1017	// Sanity check the SP.
1018	stackcheck()
1019}
1020
1021// Called from dropm to undo the effect of an minit.
1022//go:nosplit
1023func unminit() {
1024	mp := getg().m
1025	lock(&mp.threadLock)
1026	if mp.thread != 0 {
1027		stdcall1(_CloseHandle, mp.thread)
1028		mp.thread = 0
1029	}
1030	unlock(&mp.threadLock)
1031}
1032
1033// Called from exitm, but not from drop, to undo the effect of thread-owned
1034// resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
1035//go:nosplit
1036func mdestroy(mp *m) {
1037	if mp.highResTimer != 0 {
1038		stdcall1(_CloseHandle, mp.highResTimer)
1039		mp.highResTimer = 0
1040	}
1041	if mp.waitsema != 0 {
1042		stdcall1(_CloseHandle, mp.waitsema)
1043		mp.waitsema = 0
1044	}
1045	if mp.resumesema != 0 {
1046		stdcall1(_CloseHandle, mp.resumesema)
1047		mp.resumesema = 0
1048	}
1049}
1050
1051// Calling stdcall on os stack.
1052// May run during STW, so write barriers are not allowed.
1053//go:nowritebarrier
1054//go:nosplit
1055func stdcall(fn stdFunction) uintptr {
1056	gp := getg()
1057	mp := gp.m
1058	mp.libcall.fn = uintptr(unsafe.Pointer(fn))
1059	resetLibcall := false
1060	if mp.profilehz != 0 && mp.libcallsp == 0 {
1061		// leave pc/sp for cpu profiler
1062		mp.libcallg.set(gp)
1063		mp.libcallpc = getcallerpc()
1064		// sp must be the last, because once async cpu profiler finds
1065		// all three values to be non-zero, it will use them
1066		mp.libcallsp = getcallersp()
1067		resetLibcall = true // See comment in sys_darwin.go:libcCall
1068	}
1069	asmcgocall(asmstdcallAddr, unsafe.Pointer(&mp.libcall))
1070	if resetLibcall {
1071		mp.libcallsp = 0
1072	}
1073	return mp.libcall.r1
1074}
1075
1076//go:nosplit
1077func stdcall0(fn stdFunction) uintptr {
1078	mp := getg().m
1079	mp.libcall.n = 0
1080	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes
1081	return stdcall(fn)
1082}
1083
1084//go:nosplit
1085//go:cgo_unsafe_args
1086func stdcall1(fn stdFunction, a0 uintptr) uintptr {
1087	mp := getg().m
1088	mp.libcall.n = 1
1089	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
1090	return stdcall(fn)
1091}
1092
1093//go:nosplit
1094//go:cgo_unsafe_args
1095func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr {
1096	mp := getg().m
1097	mp.libcall.n = 2
1098	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
1099	return stdcall(fn)
1100}
1101
1102//go:nosplit
1103//go:cgo_unsafe_args
1104func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr {
1105	mp := getg().m
1106	mp.libcall.n = 3
1107	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
1108	return stdcall(fn)
1109}
1110
1111//go:nosplit
1112//go:cgo_unsafe_args
1113func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr {
1114	mp := getg().m
1115	mp.libcall.n = 4
1116	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
1117	return stdcall(fn)
1118}
1119
1120//go:nosplit
1121//go:cgo_unsafe_args
1122func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr {
1123	mp := getg().m
1124	mp.libcall.n = 5
1125	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
1126	return stdcall(fn)
1127}
1128
1129//go:nosplit
1130//go:cgo_unsafe_args
1131func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr {
1132	mp := getg().m
1133	mp.libcall.n = 6
1134	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
1135	return stdcall(fn)
1136}
1137
1138//go:nosplit
1139//go:cgo_unsafe_args
1140func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
1141	mp := getg().m
1142	mp.libcall.n = 7
1143	mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
1144	return stdcall(fn)
1145}
1146
1147// These must run on the system stack only.
1148func usleep2(dt int32)
1149func usleep2HighRes(dt int32)
1150func switchtothread()
1151
1152//go:nosplit
1153func osyield_no_g() {
1154	switchtothread()
1155}
1156
1157//go:nosplit
1158func osyield() {
1159	systemstack(switchtothread)
1160}
1161
1162//go:nosplit
1163func usleep_no_g(us uint32) {
1164	dt := -10 * int32(us) // relative sleep (negative), 100ns units
1165	usleep2(dt)
1166}
1167
1168//go:nosplit
1169func usleep(us uint32) {
1170	systemstack(func() {
1171		dt := -10 * int32(us) // relative sleep (negative), 100ns units
1172		// If the high-res timer is available and its handle has been allocated for this m, use it.
1173		// Otherwise fall back to the low-res one, which doesn't need a handle.
1174		if haveHighResTimer && getg().m.highResTimer != 0 {
1175			usleep2HighRes(dt)
1176		} else {
1177			usleep2(dt)
1178		}
1179	})
1180}
1181
1182func ctrlHandler(_type uint32) uintptr {
1183	var s uint32
1184
1185	switch _type {
1186	case _CTRL_C_EVENT, _CTRL_BREAK_EVENT:
1187		s = _SIGINT
1188	case _CTRL_CLOSE_EVENT, _CTRL_LOGOFF_EVENT, _CTRL_SHUTDOWN_EVENT:
1189		s = _SIGTERM
1190	default:
1191		return 0
1192	}
1193
1194	if sigsend(s) {
1195		if s == _SIGTERM {
1196			// Windows terminates the process after this handler returns.
1197			// Block indefinitely to give signal handlers a chance to clean up,
1198			// but make sure to be properly parked first, so the rest of the
1199			// program can continue executing.
1200			block()
1201		}
1202		return 1
1203	}
1204	return 0
1205}
1206
1207// called from zcallback_windows_*.s to sys_windows_*.s
1208func callbackasm1()
1209
1210var profiletimer uintptr
1211
1212func profilem(mp *m, thread uintptr) {
1213	// Align Context to 16 bytes.
1214	var c *context
1215	var cbuf [unsafe.Sizeof(*c) + 15]byte
1216	c = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&cbuf[15]))) &^ 15))
1217
1218	c.contextflags = _CONTEXT_CONTROL
1219	stdcall2(_GetThreadContext, thread, uintptr(unsafe.Pointer(c)))
1220
1221	gp := gFromSP(mp, c.sp())
1222
1223	sigprof(c.ip(), c.sp(), c.lr(), gp, mp)
1224}
1225
1226func gFromSP(mp *m, sp uintptr) *g {
1227	if gp := mp.g0; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
1228		return gp
1229	}
1230	if gp := mp.gsignal; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
1231		return gp
1232	}
1233	if gp := mp.curg; gp != nil && gp.stack.lo < sp && sp < gp.stack.hi {
1234		return gp
1235	}
1236	return nil
1237}
1238
1239func profileLoop() {
1240	stdcall2(_SetThreadPriority, currentThread, _THREAD_PRIORITY_HIGHEST)
1241
1242	for {
1243		stdcall2(_WaitForSingleObject, profiletimer, _INFINITE)
1244		first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
1245		for mp := first; mp != nil; mp = mp.alllink {
1246			if mp == getg().m {
1247				// Don't profile ourselves.
1248				continue
1249			}
1250
1251			lock(&mp.threadLock)
1252			// Do not profile threads blocked on Notes,
1253			// this includes idle worker threads,
1254			// idle timer thread, idle heap scavenger, etc.
1255			if mp.thread == 0 || mp.profilehz == 0 || mp.blocked {
1256				unlock(&mp.threadLock)
1257				continue
1258			}
1259			// Acquire our own handle to the thread.
1260			var thread uintptr
1261			if stdcall7(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
1262				print("runtime: duplicatehandle failed; errno=", getlasterror(), "\n")
1263				throw("duplicatehandle failed")
1264			}
1265			unlock(&mp.threadLock)
1266
1267			// mp may exit between the DuplicateHandle
1268			// above and the SuspendThread. The handle
1269			// will remain valid, but SuspendThread may
1270			// fail.
1271			if int32(stdcall1(_SuspendThread, thread)) == -1 {
1272				// The thread no longer exists.
1273				stdcall1(_CloseHandle, thread)
1274				continue
1275			}
1276			if mp.profilehz != 0 && !mp.blocked {
1277				// Pass the thread handle in case mp
1278				// was in the process of shutting down.
1279				profilem(mp, thread)
1280			}
1281			stdcall1(_ResumeThread, thread)
1282			stdcall1(_CloseHandle, thread)
1283		}
1284	}
1285}
1286
1287func setProcessCPUProfiler(hz int32) {
1288	if profiletimer == 0 {
1289		timer := stdcall3(_CreateWaitableTimerA, 0, 0, 0)
1290		atomic.Storeuintptr(&profiletimer, timer)
1291		newm(profileLoop, nil, -1)
1292	}
1293}
1294
1295func setThreadCPUProfiler(hz int32) {
1296	ms := int32(0)
1297	due := ^int64(^uint64(1 << 63))
1298	if hz > 0 {
1299		ms = 1000 / hz
1300		if ms == 0 {
1301			ms = 1
1302		}
1303		due = int64(ms) * -10000
1304	}
1305	stdcall6(_SetWaitableTimer, profiletimer, uintptr(unsafe.Pointer(&due)), uintptr(ms), 0, 0, 0)
1306	atomic.Store((*uint32)(unsafe.Pointer(&getg().m.profilehz)), uint32(hz))
1307}
1308
1309const preemptMSupported = true
1310
1311// suspendLock protects simultaneous SuspendThread operations from
1312// suspending each other.
1313var suspendLock mutex
1314
1315func preemptM(mp *m) {
1316	if mp == getg().m {
1317		throw("self-preempt")
1318	}
1319
1320	// Synchronize with external code that may try to ExitProcess.
1321	if !atomic.Cas(&mp.preemptExtLock, 0, 1) {
1322		// External code is running. Fail the preemption
1323		// attempt.
1324		atomic.Xadd(&mp.preemptGen, 1)
1325		return
1326	}
1327
1328	// Acquire our own handle to mp's thread.
1329	lock(&mp.threadLock)
1330	if mp.thread == 0 {
1331		// The M hasn't been minit'd yet (or was just unminit'd).
1332		unlock(&mp.threadLock)
1333		atomic.Store(&mp.preemptExtLock, 0)
1334		atomic.Xadd(&mp.preemptGen, 1)
1335		return
1336	}
1337	var thread uintptr
1338	if stdcall7(_DuplicateHandle, currentProcess, mp.thread, currentProcess, uintptr(unsafe.Pointer(&thread)), 0, 0, _DUPLICATE_SAME_ACCESS) == 0 {
1339		print("runtime.preemptM: duplicatehandle failed; errno=", getlasterror(), "\n")
1340		throw("runtime.preemptM: duplicatehandle failed")
1341	}
1342	unlock(&mp.threadLock)
1343
1344	// Prepare thread context buffer. This must be aligned to 16 bytes.
1345	var c *context
1346	var cbuf [unsafe.Sizeof(*c) + 15]byte
1347	c = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&cbuf[15]))) &^ 15))
1348	c.contextflags = _CONTEXT_CONTROL
1349
1350	// Serialize thread suspension. SuspendThread is asynchronous,
1351	// so it's otherwise possible for two threads to suspend each
1352	// other and deadlock. We must hold this lock until after
1353	// GetThreadContext, since that blocks until the thread is
1354	// actually suspended.
1355	lock(&suspendLock)
1356
1357	// Suspend the thread.
1358	if int32(stdcall1(_SuspendThread, thread)) == -1 {
1359		unlock(&suspendLock)
1360		stdcall1(_CloseHandle, thread)
1361		atomic.Store(&mp.preemptExtLock, 0)
1362		// The thread no longer exists. This shouldn't be
1363		// possible, but just acknowledge the request.
1364		atomic.Xadd(&mp.preemptGen, 1)
1365		return
1366	}
1367
1368	// We have to be very careful between this point and once
1369	// we've shown mp is at an async safe-point. This is like a
1370	// signal handler in the sense that mp could have been doing
1371	// anything when we stopped it, including holding arbitrary
1372	// locks.
1373
1374	// We have to get the thread context before inspecting the M
1375	// because SuspendThread only requests a suspend.
1376	// GetThreadContext actually blocks until it's suspended.
1377	stdcall2(_GetThreadContext, thread, uintptr(unsafe.Pointer(c)))
1378
1379	unlock(&suspendLock)
1380
1381	// Does it want a preemption and is it safe to preempt?
1382	gp := gFromSP(mp, c.sp())
1383	if gp != nil && wantAsyncPreempt(gp) {
1384		if ok, newpc := isAsyncSafePoint(gp, c.ip(), c.sp(), c.lr()); ok {
1385			// Inject call to asyncPreempt
1386			targetPC := abi.FuncPCABI0(asyncPreempt)
1387			switch GOARCH {
1388			default:
1389				throw("unsupported architecture")
1390			case "386", "amd64":
1391				// Make it look like the thread called targetPC.
1392				sp := c.sp()
1393				sp -= goarch.PtrSize
1394				*(*uintptr)(unsafe.Pointer(sp)) = newpc
1395				c.set_sp(sp)
1396				c.set_ip(targetPC)
1397
1398			case "arm":
1399				// Push LR. The injected call is responsible
1400				// for restoring LR. gentraceback is aware of
1401				// this extra slot. See sigctxt.pushCall in
1402				// signal_arm.go, which is similar except we
1403				// subtract 1 from IP here.
1404				sp := c.sp()
1405				sp -= goarch.PtrSize
1406				c.set_sp(sp)
1407				*(*uint32)(unsafe.Pointer(sp)) = uint32(c.lr())
1408				c.set_lr(newpc - 1)
1409				c.set_ip(targetPC)
1410
1411			case "arm64":
1412				// Push LR. The injected call is responsible
1413				// for restoring LR. gentraceback is aware of
1414				// this extra slot. See sigctxt.pushCall in
1415				// signal_arm64.go.
1416				sp := c.sp() - 16 // SP needs 16-byte alignment
1417				c.set_sp(sp)
1418				*(*uint64)(unsafe.Pointer(sp)) = uint64(c.lr())
1419				c.set_lr(newpc)
1420				c.set_ip(targetPC)
1421			}
1422			stdcall2(_SetThreadContext, thread, uintptr(unsafe.Pointer(c)))
1423		}
1424	}
1425
1426	atomic.Store(&mp.preemptExtLock, 0)
1427
1428	// Acknowledge the preemption.
1429	atomic.Xadd(&mp.preemptGen, 1)
1430
1431	stdcall1(_ResumeThread, thread)
1432	stdcall1(_CloseHandle, thread)
1433}
1434
1435// osPreemptExtEnter is called before entering external code that may
1436// call ExitProcess.
1437//
1438// This must be nosplit because it may be called from a syscall with
1439// untyped stack slots, so the stack must not be grown or scanned.
1440//
1441//go:nosplit
1442func osPreemptExtEnter(mp *m) {
1443	for !atomic.Cas(&mp.preemptExtLock, 0, 1) {
1444		// An asynchronous preemption is in progress. It's not
1445		// safe to enter external code because it may call
1446		// ExitProcess and deadlock with SuspendThread.
1447		// Ideally we would do the preemption ourselves, but
1448		// can't since there may be untyped syscall arguments
1449		// on the stack. Instead, just wait and encourage the
1450		// SuspendThread APC to run. The preemption should be
1451		// done shortly.
1452		osyield()
1453	}
1454	// Asynchronous preemption is now blocked.
1455}
1456
1457// osPreemptExtExit is called after returning from external code that
1458// may call ExitProcess.
1459//
1460// See osPreemptExtEnter for why this is nosplit.
1461//
1462//go:nosplit
1463func osPreemptExtExit(mp *m) {
1464	atomic.Store(&mp.preemptExtLock, 0)
1465}
1466