github.com/rafaeltorres324/go/src@v0.0.0-20210519164414-9fdf653a9838/runtime/os_windows.go (about)

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