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