...

Source file src/pkg/runtime/os_windows.go

     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		"unsafe"
    10	)
    11	
    12	// TODO(brainman): should not need those
    13	const (
    14		_NSIG = 65
    15	)
    16	
    17	//go:cgo_import_dynamic runtime._AddVectoredExceptionHandler AddVectoredExceptionHandler%2 "kernel32.dll"
    18	//go:cgo_import_dynamic runtime._CloseHandle CloseHandle%1 "kernel32.dll"
    19	//go:cgo_import_dynamic runtime._CreateEventA CreateEventA%4 "kernel32.dll"
    20	//go:cgo_import_dynamic runtime._CreateIoCompletionPort CreateIoCompletionPort%4 "kernel32.dll"
    21	//go:cgo_import_dynamic runtime._CreateThread CreateThread%6 "kernel32.dll"
    22	//go:cgo_import_dynamic runtime._CreateWaitableTimerA CreateWaitableTimerA%3 "kernel32.dll"
    23	//go:cgo_import_dynamic runtime._DuplicateHandle DuplicateHandle%7 "kernel32.dll"
    24	//go:cgo_import_dynamic runtime._ExitProcess ExitProcess%1 "kernel32.dll"
    25	//go:cgo_import_dynamic runtime._FreeEnvironmentStringsW FreeEnvironmentStringsW%1 "kernel32.dll"
    26	//go:cgo_import_dynamic runtime._GetConsoleMode GetConsoleMode%2 "kernel32.dll"
    27	//go:cgo_import_dynamic runtime._GetEnvironmentStringsW GetEnvironmentStringsW%0 "kernel32.dll"
    28	//go:cgo_import_dynamic runtime._GetProcAddress GetProcAddress%2 "kernel32.dll"
    29	//go:cgo_import_dynamic runtime._GetProcessAffinityMask GetProcessAffinityMask%3 "kernel32.dll"
    30	//go:cgo_import_dynamic runtime._GetQueuedCompletionStatus GetQueuedCompletionStatus%5 "kernel32.dll"
    31	//go:cgo_import_dynamic runtime._GetStdHandle GetStdHandle%1 "kernel32.dll"
    32	//go:cgo_import_dynamic runtime._GetSystemDirectoryA GetSystemDirectoryA%2 "kernel32.dll"
    33	//go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll"
    34	//go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll"
    35	//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll"
    36	//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll"
    37	//go:cgo_import_dynamic runtime._ResumeThread ResumeThread%1 "kernel32.dll"
    38	//go:cgo_import_dynamic runtime._SetConsoleCtrlHandler SetConsoleCtrlHandler%2 "kernel32.dll"
    39	//go:cgo_import_dynamic runtime._SetErrorMode SetErrorMode%1 "kernel32.dll"
    40	//go:cgo_import_dynamic runtime._SetEvent SetEvent%1 "kernel32.dll"
    41	//go:cgo_import_dynamic runtime._SetProcessPriorityBoost SetProcessPriorityBoost%2 "kernel32.dll"
    42	//go:cgo_import_dynamic runtime._SetThreadPriority SetThreadPriority%2 "kernel32.dll"
    43	//go:cgo_import_dynamic runtime._SetUnhandledExceptionFilter SetUnhandledExceptionFilter%1 "kernel32.dll"
    44	//go:cgo_import_dynamic runtime._SetWaitableTimer SetWaitableTimer%6 "kernel32.dll"
    45	//go:cgo_import_dynamic runtime._SuspendThread SuspendThread%1 "kernel32.dll"
    46	//go:cgo_import_dynamic runtime._SwitchToThread SwitchToThread%0 "kernel32.dll"
    47	//go:cgo_import_dynamic runtime._TlsAlloc TlsAlloc%0 "kernel32.dll"
    48	//go:cgo_import_dynamic runtime._VirtualAlloc VirtualAlloc%4 "kernel32.dll"
    49	//go:cgo_import_dynamic runtime._VirtualFree VirtualFree%3 "kernel32.dll"
    50	//go:cgo_import_dynamic runtime._VirtualQuery VirtualQuery%3 "kernel32.dll"
    51	//go:cgo_import_dynamic runtime._WaitForSingleObject WaitForSingleObject%2 "kernel32.dll"
    52	//go:cgo_import_dynamic runtime._WaitForMultipleObjects WaitForMultipleObjects%4 "kernel32.dll"
    53	//go:cgo_import_dynamic runtime._WriteConsoleW WriteConsoleW%5 "kernel32.dll"
    54	//go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll"
    55	
    56	type stdFunction unsafe.Pointer
    57	
    58	var (
    59		// Following syscalls are available on every Windows PC.
    60		// All these variables are set by the Windows executable
    61		// loader before the Go program starts.
    62		_AddVectoredExceptionHandler,
    63		_CloseHandle,
    64		_CreateEventA,
    65		_CreateIoCompletionPort,
    66		_CreateThread,
    67		_CreateWaitableTimerA,
    68		_DuplicateHandle,
    69		_ExitProcess,
    70		_FreeEnvironmentStringsW,
    71		_GetConsoleMode,
    72		_GetEnvironmentStringsW,
    73		_GetProcAddress,
    74		_GetProcessAffinityMask,
    75		_GetQueuedCompletionStatus,
    76		_GetStdHandle,
    77		_GetSystemDirectoryA,
    78		_GetSystemInfo,
    79		_GetSystemTimeAsFileTime,
    80		_GetThreadContext,
    81		_LoadLibraryW,
    82		_LoadLibraryA,
    83		_QueryPerformanceCounter,
    84		_QueryPerformanceFrequency,
    85		_ResumeThread,
    86		_SetConsoleCtrlHandler,
    87		_SetErrorMode,
    88		_SetEvent,
    89		_SetProcessPriorityBoost,
    90		_SetThreadPriority,
    91		_SetUnhandledExceptionFilter,
    92		_SetWaitableTimer,
    93		_SuspendThread,
    94		_SwitchToThread,
    95		_TlsAlloc,
    96		_VirtualAlloc,
    97		_VirtualFree,
    98		_VirtualQuery,
    99		_WaitForSingleObject,
   100		_WaitForMultipleObjects,
   101		_WriteConsoleW,
   102		_WriteFile,
   103		_ stdFunction
   104	
   105		// Following syscalls are only available on some Windows PCs.
   106		// We will load syscalls, if available, before using them.
   107		_AddDllDirectory,
   108		_AddVectoredContinueHandler,
   109		_GetQueuedCompletionStatusEx,
   110		_LoadLibraryExA,
   111		_LoadLibraryExW,
   112		_ stdFunction
   113	
   114		// Use RtlGenRandom to generate cryptographically random data.
   115		// This approach has been recommended by Microsoft (see issue
   116		// 15589 for details).
   117		// The RtlGenRandom is not listed in advapi32.dll, instead
   118		// RtlGenRandom function can be found by searching for SystemFunction036.
   119		// Also some versions of Mingw cannot link to SystemFunction036
   120		// when building executable as Cgo. So load SystemFunction036
   121		// manually during runtime startup.
   122		_RtlGenRandom stdFunction
   123	
   124		// Load ntdll.dll manually during startup, otherwise Mingw
   125		// links wrong printf function to cgo executable (see issue
   126		// 12030 for details).
   127		_NtWaitForSingleObject stdFunction
   128	
   129		// These are from non-kernel32.dll, so we prefer to LoadLibraryEx them.
   130		_timeBeginPeriod,
   131		_timeEndPeriod,
   132		_WSAGetOverlappedResult,
   133		_ stdFunction
   134	)
   135	
   136	// Function to be called by windows CreateThread
   137	// to start new os thread.
   138	func tstart_stdcall(newm *m)
   139	
   140	// Called by OS using stdcall ABI.
   141	func ctrlhandler()
   142	
   143	type mOS struct {
   144		waitsema   uintptr // semaphore for parking on locks
   145		resumesema uintptr // semaphore to indicate suspend/resume
   146	}
   147	
   148	//go:linkname os_sigpipe os.sigpipe
   149	func os_sigpipe() {
   150		throw("too many writes on closed pipe")
   151	}
   152	
   153	// Stubs so tests can link correctly. These should never be called.
   154	func open(name *byte, mode, perm int32) int32 {
   155		throw("unimplemented")
   156		return -1
   157	}
   158	func closefd(fd int32) int32 {
   159		throw("unimplemented")
   160		return -1
   161	}
   162	func read(fd int32, p unsafe.Pointer, n int32) int32 {
   163		throw("unimplemented")
   164		return -1
   165	}
   166	
   167	type sigset struct{}
   168	
   169	// Call a Windows function with stdcall conventions,
   170	// and switch to os stack during the call.
   171	func asmstdcall(fn unsafe.Pointer)
   172	
   173	var asmstdcallAddr unsafe.Pointer
   174	
   175	func windowsFindfunc(lib uintptr, name []byte) stdFunction {
   176		if name[len(name)-1] != 0 {
   177			throw("usage")
   178		}
   179		f := stdcall2(_GetProcAddress, lib, uintptr(unsafe.Pointer(&name[0])))
   180		return stdFunction(unsafe.Pointer(f))
   181	}
   182	
   183	var sysDirectory [521]byte
   184	var sysDirectoryLen uintptr
   185	
   186	func windowsLoadSystemLib(name []byte) uintptr {
   187		if useLoadLibraryEx {
   188			return stdcall3(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32)
   189		} else {
   190			if sysDirectoryLen == 0 {
   191				l := stdcall2(_GetSystemDirectoryA, uintptr(unsafe.Pointer(&sysDirectory[0])), uintptr(len(sysDirectory)-1))
   192				if l == 0 || l > uintptr(len(sysDirectory)-1) {
   193					throw("Unable to determine system directory")
   194				}
   195				sysDirectory[l] = '\\'
   196				sysDirectoryLen = l + 1
   197			}
   198			absName := append(sysDirectory[:sysDirectoryLen], name...)
   199			return stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0])))
   200		}
   201	}
   202	
   203	func loadOptionalSyscalls() {
   204		var kernel32dll = []byte("kernel32.dll\000")
   205		k32 := stdcall1(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0])))
   206		if k32 == 0 {
   207			throw("kernel32.dll not found")
   208		}
   209		_AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000"))
   210		_AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000"))
   211		_GetQueuedCompletionStatusEx = windowsFindfunc(k32, []byte("GetQueuedCompletionStatusEx\000"))
   212		_LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000"))
   213		_LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000"))
   214		useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil)
   215	
   216		var advapi32dll = []byte("advapi32.dll\000")
   217		a32 := windowsLoadSystemLib(advapi32dll)
   218		if a32 == 0 {
   219			throw("advapi32.dll not found")
   220		}
   221		_RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000"))
   222	
   223		var ntdll = []byte("ntdll.dll\000")
   224		n32 := windowsLoadSystemLib(ntdll)
   225		if n32 == 0 {
   226			throw("ntdll.dll not found")
   227		}
   228		_NtWaitForSingleObject = windowsFindfunc(n32, []byte("NtWaitForSingleObject\000"))
   229	
   230		if GOARCH == "arm" {
   231			_QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
   232			if _QueryPerformanceCounter == nil {
   233				throw("could not find QPC syscalls")
   234			}
   235		}
   236	
   237		var winmmdll = []byte("winmm.dll\000")
   238		m32 := windowsLoadSystemLib(winmmdll)
   239		if m32 == 0 {
   240			throw("winmm.dll not found")
   241		}
   242		_timeBeginPeriod = windowsFindfunc(m32, []byte("timeBeginPeriod\000"))
   243		_timeEndPeriod = windowsFindfunc(m32, []byte("timeEndPeriod\000"))
   244		if _timeBeginPeriod == nil || _timeEndPeriod == nil {
   245			throw("timeBegin/EndPeriod not found")
   246		}
   247	
   248		var ws232dll = []byte("ws2_32.dll\000")
   249		ws232 := windowsLoadSystemLib(ws232dll)
   250		if ws232 == 0 {
   251			throw("ws2_32.dll not found")
   252		}
   253		_WSAGetOverlappedResult = windowsFindfunc(ws232, []byte("WSAGetOverlappedResult\000"))
   254		if _WSAGetOverlappedResult == nil {
   255			throw("WSAGetOverlappedResult not found")
   256		}
   257	
   258		if windowsFindfunc(n32, []byte("wine_get_version\000")) != nil {
   259			// running on Wine
   260			initWine(k32)
   261		}
   262	}
   263	
   264	func monitorSuspendResume() {
   265		const (
   266			_DEVICE_NOTIFY_CALLBACK = 2
   267			_ERROR_FILE_NOT_FOUND   = 2
   268		)
   269		type _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS struct {
   270			callback uintptr
   271			context  uintptr
   272		}
   273	
   274		powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000"))
   275		if powrprof == 0 {
   276			return // Running on Windows 7, where we don't need it anyway.
   277		}
   278		powerRegisterSuspendResumeNotification := windowsFindfunc(powrprof, []byte("PowerRegisterSuspendResumeNotification\000"))
   279		if powerRegisterSuspendResumeNotification == nil {
   280			return // Running on Windows 7, where we don't need it anyway.
   281		}
   282		var fn interface{} = func(context uintptr, changeType uint32, setting uintptr) uintptr {
   283			for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink {
   284				if mp.resumesema != 0 {
   285					stdcall1(_SetEvent, mp.resumesema)
   286				}
   287			}
   288			return 0
   289		}
   290		params := _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS{
   291			callback: compileCallback(*efaceOf(&fn), true),
   292		}
   293		handle := uintptr(0)
   294		ret := stdcall3(powerRegisterSuspendResumeNotification, _DEVICE_NOTIFY_CALLBACK,
   295			uintptr(unsafe.Pointer(&params)), uintptr(unsafe.Pointer(&handle)))
   296		// This function doesn't use GetLastError(), so we use the return value directly.
   297		switch ret {
   298		case 0:
   299			return // Successful, nothing more to do.
   300		case _ERROR_FILE_NOT_FOUND:
   301			// Systems without access to the suspend/resume notifier
   302			// also have their clock on "program time", and therefore
   303			// don't want or need this anyway.
   304			return
   305		default:
   306			println("runtime: PowerRegisterSuspendResumeNotification failed with errno=", ret)
   307			throw("runtime: PowerRegisterSuspendResumeNotification failure")
   308		}
   309	}
   310	
   311	//go:nosplit
   312	func getLoadLibrary() uintptr {
   313		return uintptr(unsafe.Pointer(_LoadLibraryW))
   314	}
   315	
   316	//go:nosplit
   317	func getLoadLibraryEx() uintptr {
   318		return uintptr(unsafe.Pointer(_LoadLibraryExW))
   319	}
   320	
   321	//go:nosplit
   322	func getGetProcAddress() uintptr {
   323		return uintptr(unsafe.Pointer(_GetProcAddress))
   324	}
   325	
   326	func getproccount() int32 {
   327		var mask, sysmask uintptr
   328		ret := stdcall3(_GetProcessAffinityMask, currentProcess, uintptr(unsafe.Pointer(&mask)), uintptr(unsafe.Pointer(&sysmask)))
   329		if ret != 0 {
   330			n := 0
   331			maskbits := int(unsafe.Sizeof(mask) * 8)
   332			for i := 0; i < maskbits; i++ {
   333				if mask&(1<<uint(i)) != 0 {
   334					n++
   335				}
   336			}
   337			if n != 0 {
   338				return int32(n)
   339			}
   340		}
   341		// use GetSystemInfo if GetProcessAffinityMask fails
   342		var info systeminfo
   343		stdcall1(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
   344		return int32(info.dwnumberofprocessors)
   345	}
   346	
   347	func getPageSize() uintptr {
   348		var info systeminfo
   349		stdcall1(_GetSystemInfo, uintptr(unsafe.Pointer(&info)))
   350		return uintptr(info.dwpagesize)
   351	}
   352	
   353	const (
   354		currentProcess = ^uintptr(0) // -1 = current process
   355		currentThread  = ^uintptr(1) // -2 = current thread
   356	)
   357	
   358	// in sys_windows_386.s and sys_windows_amd64.s:
   359	func externalthreadhandler()
   360	func getlasterror() uint32
   361	func setlasterror(err uint32)
   362	
   363	// When loading DLLs, we prefer to use LoadLibraryEx with
   364	// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not
   365	// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_*
   366	// flags are not available on some versions of Windows without a
   367	// security patch.
   368	//
   369	// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says:
   370	// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows
   371	// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on
   372	// systems that have KB2533623 installed. To determine whether the
   373	// flags are available, use GetProcAddress to get the address of the
   374	// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories
   375	// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_*
   376	// flags can be used with LoadLibraryEx."
   377	var useLoadLibraryEx bool
   378	
   379	var timeBeginPeriodRetValue uint32
   380	
   381	// osRelaxMinNS indicates that sysmon shouldn't osRelax if the next
   382	// timer is less than 60 ms from now. Since osRelaxing may reduce
   383	// timer resolution to 15.6 ms, this keeps timer error under roughly 1
   384	// part in 4.
   385	const osRelaxMinNS = 60 * 1e6
   386	
   387	// osRelax is called by the scheduler when transitioning to and from
   388	// all Ps being idle.
   389	//
   390	// On Windows, it adjusts the system-wide timer resolution. Go needs a
   391	// high resolution timer while running and there's little extra cost
   392	// if we're already using the CPU, but if all Ps are idle there's no
   393	// need to consume extra power to drive the high-res timer.
   394	func osRelax(relax bool) uint32 {
   395		if relax {
   396			return uint32(stdcall1(_timeEndPeriod, 1))
   397		} else {
   398			return uint32(stdcall1(_timeBeginPeriod, 1))
   399		}
   400	}
   401	
   402	func osinit() {
   403		asmstdcallAddr = unsafe.Pointer(funcPC(asmstdcall))
   404		usleep2Addr = unsafe.Pointer(funcPC(usleep2))
   405		switchtothreadAddr = unsafe.Pointer(funcPC(switchtothread))
   406	
   407		setBadSignalMsg()
   408	
   409		loadOptionalSyscalls()
   410	
   411		disableWER()
   412	
   413		initExceptionHandler()
   414	
   415		stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
   416	
   417		timeBeginPeriodRetValue = osRelax(false)
   418	
   419		ncpu = getproccount()
   420	
   421		physPageSize = getPageSize()
   422	
   423		// Windows dynamic priority boosting assumes that a process has different types
   424		// of dedicated threads -- GUI, IO, computational, etc. Go processes use
   425		// equivalent threads that all do a mix of GUI, IO, computations, etc.
   426		// In such context dynamic priority boosting does nothing but harm, so we turn it off.
   427		stdcall2(_SetProcessPriorityBoost, currentProcess, 1)
   428	}
   429	
   430	func nanotime() int64
   431	
   432	// useQPCTime controls whether time.now and nanotime use QueryPerformanceCounter.
   433	// This is only set to 1 when running under Wine.
   434	var useQPCTime uint8
   435	
   436	var qpcStartCounter int64
   437	var qpcMultiplier int64
   438	
   439	//go:nosplit
   440	func nanotimeQPC() int64 {
   441		var counter int64 = 0
   442		stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&counter)))
   443	
   444		// returns number of nanoseconds
   445		return (counter - qpcStartCounter) * qpcMultiplier
   446	}
   447	
   448	//go:nosplit
   449	func nowQPC() (sec int64, nsec int32, mono int64) {
   450		var ft int64
   451		stdcall1(_GetSystemTimeAsFileTime, uintptr(unsafe.Pointer(&ft)))
   452	
   453		t := (ft - 116444736000000000) * 100
   454	
   455		sec = t / 1000000000
   456		nsec = int32(t - sec*1000000000)
   457	
   458		mono = nanotimeQPC()
   459		return
   460	}
   461	
   462	func initWine(k32 uintptr) {
   463		_GetSystemTimeAsFileTime = windowsFindfunc(k32, []byte("GetSystemTimeAsFileTime\000"))
   464		if _GetSystemTimeAsFileTime == nil {
   465			throw("could not find GetSystemTimeAsFileTime() syscall")
   466		}
   467	
   468		_QueryPerformanceCounter = windowsFindfunc(k32, []byte("QueryPerformanceCounter\000"))
   469		_QueryPerformanceFrequency = windowsFindfunc(k32, []byte("QueryPerformanceFrequency\000"))
   470		if _QueryPerformanceCounter == nil || _QueryPerformanceFrequency == nil {
   471			throw("could not find QPC syscalls")
   472		}
   473	
   474		// We can not simply fallback to GetSystemTimeAsFileTime() syscall, since its time is not monotonic,
   475		// instead we use QueryPerformanceCounter family of syscalls to implement monotonic timer
   476		// https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
   477	
   478		var tmp int64
   479		stdcall1(_QueryPerformanceFrequency, uintptr(unsafe.Pointer(&tmp)))
   480		if tmp == 0 {
   481			throw("QueryPerformanceFrequency syscall returned zero, running on unsupported hardware")
   482		}
   483	
   484		// This should not overflow, it is a number of ticks of the performance counter per second,
   485		// its resolution is at most 10 per usecond (on Wine, even smaller on real hardware), so it will be at most 10 millions here,
   486		// panic if overflows.
   487		if tmp > (1<<31 - 1) {
   488			throw("QueryPerformanceFrequency overflow 32 bit divider, check nosplit discussion to proceed")
   489		}
   490		qpcFrequency := int32(tmp)
   491		stdcall1(_QueryPerformanceCounter, uintptr(unsafe.Pointer(&qpcStartCounter)))
   492	
   493		// Since we are supposed to run this time calls only on Wine, it does not lose precision,
   494		// since Wine's timer is kind of emulated at 10 Mhz, so it will be a nice round multiplier of 100
   495		// but for general purpose system (like 3.3 Mhz timer on i7) it will not be very precise.
   496		// We have to do it this way (or similar), since multiplying QPC counter by 100 millions overflows
   497		// int64 and resulted time will always be invalid.
   498		qpcMultiplier = int64(timediv(1000000000, qpcFrequency, nil))
   499	
   500		useQPCTime = 1
   501	}
   502	
   503	//go:nosplit
   504	func getRandomData(r []byte) {
   505		n := 0
   506		if stdcall2(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 {
   507			n = len(r)
   508		}
   509		extendRandom(r, n)
   510	}
   511	
   512	func goenvs() {
   513		// strings is a pointer to environment variable pairs in the form:
   514		//     "envA=valA\x00envB=valB\x00\x00" (in UTF-16)
   515		// Two consecutive zero bytes end the list.
   516		strings := unsafe.Pointer(stdcall0(_GetEnvironmentStringsW))
   517		p := (*[1 << 24]uint16)(strings)[:]
   518	
   519		n := 0
   520		for from, i := 0, 0; true; i++ {
   521			if p[i] == 0 {
   522				// empty string marks the end
   523				if i == from {
   524					break
   525				}
   526				from = i + 1
   527				n++
   528			}
   529		}
   530		envs = make([]string, n)
   531	
   532		for i := range envs {
   533			envs[i] = gostringw(&p[0])
   534			for p[0] != 0 {
   535				p = p[1:]
   536			}
   537			p = p[1:] // skip nil byte
   538		}
   539	
   540		stdcall1(_FreeEnvironmentStringsW, uintptr(strings))
   541	
   542		// We call this all the way here, late in init, so that malloc works
   543		// for the callback function this generates.
   544		monitorSuspendResume()
   545	}
   546	
   547	// exiting is set to non-zero when the process is exiting.
   548	var exiting uint32
   549	
   550	//go:nosplit
   551	func exit(code int32) {
   552		atomic.Store(&exiting, 1)
   553		stdcall1(_ExitProcess, uintptr(code))
   554	}
   555	
   556	//go:nosplit
   557	func write(fd uintptr, buf unsafe.Pointer, n int32) int32 {
   558		const (
   559			_STD_OUTPUT_HANDLE = ^uintptr(10) // -11
   560			_STD_ERROR_HANDLE  = ^uintptr(11) // -12
   561		)
   562		var handle uintptr
   563		switch fd {
   564		case 1:
   565			handle = stdcall1(_GetStdHandle, _STD_OUTPUT_HANDLE)
   566		case 2:
   567			handle = stdcall1(_GetStdHandle, _STD_ERROR_HANDLE)
   568		default:
   569			// assume fd is real windows handle.
   570			handle = fd
   571		}
   572		isASCII := true
   573		b := (*[1 << 30]byte)(buf)[:n]
   574		for _, x := range b {
   575			if x >= 0x80 {
   576				isASCII = false
   577				break
   578			}
   579		}
   580	
   581		if !isASCII {
   582			var m uint32
   583			isConsole := stdcall2(_GetConsoleMode, handle, uintptr(unsafe.Pointer(&m))) != 0
   584			// If this is a console output, various non-unicode code pages can be in use.
   585			// Use the dedicated WriteConsole call to ensure unicode is printed correctly.
   586			if isConsole {
   587				return int32(writeConsole(handle, buf, n))
   588			}
   589		}
   590		var written uint32
   591		stdcall5(_WriteFile, handle, uintptr(buf), uintptr(n), uintptr(unsafe.Pointer(&written)), 0)
   592		return int32(written)
   593	}
   594	
   595	var (
   596		utf16ConsoleBack     [1000]uint16
   597		utf16ConsoleBackLock mutex
   598	)
   599	
   600	// writeConsole writes bufLen bytes from buf to the console File.
   601	// It returns the number of bytes written.
   602	func writeConsole(handle uintptr, buf unsafe.Pointer, bufLen int32) int {
   603		const surr2 = (surrogateMin + surrogateMax + 1) / 2
   604	
   605		// Do not use defer for unlock. May cause issues when printing a panic.
   606		lock(&utf16ConsoleBackLock)
   607	
   608		b := (*[1 << 30]byte)(buf)[:bufLen]
   609		s := *(*string)(unsafe.Pointer(&b))
   610	
   611		utf16tmp := utf16ConsoleBack[:]
   612	
   613		total := len(s)
   614		w := 0
   615		for _, r := range s {
   616			if w >= len(utf16tmp)-2 {
   617				writeConsoleUTF16(handle, utf16tmp[:w])
   618				w = 0
   619			}
   620			if r < 0x10000 {
   621				utf16tmp[w] = uint16(r)
   622				w++
   623			} else {
   624				r -= 0x10000
   625				utf16tmp[w] = surrogateMin + uint16(r>>10)&0x3ff
   626				utf16tmp[w+1] = surr2 + uint16(r)&0x3ff
   627				w += 2
   628			}
   629		}
   630		writeConsoleUTF16(handle, utf16tmp[:w])
   631		unlock(&utf16ConsoleBackLock)
   632		return total
   633	}
   634	
   635	// writeConsoleUTF16 is the dedicated windows calls that correctly prints
   636	// to the console regardless of the current code page. Input is utf-16 code points.
   637	// The handle must be a console handle.
   638	func writeConsoleUTF16(handle uintptr, b []uint16) {
   639		l := uint32(len(b))
   640		if l == 0 {
   641			return
   642		}
   643		var written uint32
   644		stdcall5(_WriteConsoleW,
   645			handle,
   646			uintptr(unsafe.Pointer(&b[0])),
   647			uintptr(l),
   648			uintptr(unsafe.Pointer(&written)),
   649			0,
   650		)
   651		return
   652	}
   653	
   654	//go:nosplit
   655	func semasleep(ns int64) int32 {
   656		const (
   657			_WAIT_ABANDONED = 0x00000080
   658			_WAIT_OBJECT_0  = 0x00000000
   659			_WAIT_TIMEOUT   = 0x00000102
   660			_WAIT_FAILED    = 0xFFFFFFFF
   661		)
   662	
   663		var result uintptr
   664		if ns < 0 {
   665			result = stdcall2(_WaitForSingleObject, getg().m.waitsema, uintptr(_INFINITE))
   666		} else {
   667			start := nanotime()
   668			elapsed := int64(0)
   669			for {
   670				ms := int64(timediv(ns-elapsed, 1000000, nil))
   671				if ms == 0 {
   672					ms = 1
   673				}
   674				result = stdcall4(_WaitForMultipleObjects, 2,
   675					uintptr(unsafe.Pointer(&[2]uintptr{getg().m.waitsema, getg().m.resumesema})),
   676					0, uintptr(ms))
   677				if result != _WAIT_OBJECT_0+1 {
   678					// Not a suspend/resume event
   679					break
   680				}
   681				elapsed = nanotime() - start
   682				if elapsed >= ns {
   683					return -1
   684				}
   685			}
   686		}
   687		switch result {
   688		case _WAIT_OBJECT_0: // Signaled
   689			return 0
   690	
   691		case _WAIT_TIMEOUT:
   692			return -1
   693	
   694		case _WAIT_ABANDONED:
   695			systemstack(func() {
   696				throw("runtime.semasleep wait_abandoned")
   697			})
   698	
   699		case _WAIT_FAILED:
   700			systemstack(func() {
   701				print("runtime: waitforsingleobject wait_failed; errno=", getlasterror(), "\n")
   702				throw("runtime.semasleep wait_failed")
   703			})
   704	
   705		default:
   706			systemstack(func() {
   707				print("runtime: waitforsingleobject unexpected; result=", result, "\n")
   708				throw("runtime.semasleep unexpected")
   709			})
   710		}
   711	
   712		return -1 // unreachable
   713	}
   714	
   715	//go:nosplit
   716	func semawakeup(mp *m) {
   717		if stdcall1(_SetEvent, mp.waitsema) == 0 {
   718			systemstack(func() {
   719				print("runtime: setevent failed; errno=", getlasterror(), "\n")
   720				throw("runtime.semawakeup")
   721			})
   722		}
   723	}
   724	
   725	//go:nosplit
   726	func semacreate(mp *m) {
   727		if mp.waitsema != 0 {
   728			return
   729		}
   730		mp.waitsema = stdcall4(_CreateEventA, 0, 0, 0, 0)
   731		if mp.waitsema == 0 {
   732			systemstack(func() {
   733				print("runtime: createevent failed; errno=", getlasterror(), "\n")
   734				throw("runtime.semacreate")
   735			})
   736		}
   737		mp.resumesema = stdcall4(_CreateEventA, 0, 0, 0, 0)
   738		if mp.resumesema == 0 {
   739			systemstack(func() {
   740				print("runtime: createevent failed; errno=", getlasterror(), "\n")
   741				throw("runtime.semacreate")
   742			})
   743			stdcall1(_CloseHandle, mp.waitsema)
   744			mp.waitsema = 0
   745		}
   746	}
   747	
   748	// May run with m.p==nil, so write barriers are not allowed. This
   749	// function is called by newosproc0, so it is also required to
   750	// operate without stack guards.
   751	//go:nowritebarrierrec
   752	//go:nosplit
   753	func newosproc(mp *m) {
   754		// We pass 0 for the stack size to use the default for this binary.
   755		thandle := stdcall6(_CreateThread, 0, 0,
   756			funcPC(tstart_stdcall), uintptr(unsafe.Pointer(mp)),
   757			0, 0)
   758	
   759		if thandle == 0 {
   760			if atomic.Load(&exiting) != 0 {
   761				// CreateThread may fail if called
   762				// concurrently with ExitProcess. If this
   763				// happens, just freeze this thread and let
   764				// the process exit. See issue #18253.
   765				lock(&deadlock)
   766				lock(&deadlock)
   767			}
   768			print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", getlasterror(), ")\n")
   769			throw("runtime.newosproc")
   770		}
   771	
   772		// Close thandle to avoid leaking the thread object if it exits.
   773		stdcall1(_CloseHandle, thandle)
   774	}
   775	
   776	// Used by the C library build mode. On Linux this function would allocate a
   777	// stack, but that's not necessary for Windows. No stack guards are present
   778	// and the GC has not been initialized, so write barriers will fail.
   779	//go:nowritebarrierrec
   780	//go:nosplit
   781	func newosproc0(mp *m, stk unsafe.Pointer) {
   782		// TODO: this is completely broken. The args passed to newosproc0 (in asm_amd64.s)
   783		// are stacksize and function, not *m and stack.
   784		// Check os_linux.go for an implemention that might actually work.
   785		throw("bad newosproc0")
   786	}
   787	
   788	func exitThread(wait *uint32) {
   789		// We should never reach exitThread on Windows because we let
   790		// the OS clean up threads.
   791		throw("exitThread")
   792	}
   793	
   794	// Called to initialize a new m (including the bootstrap m).
   795	// Called on the parent thread (main thread in case of bootstrap), can allocate memory.
   796	func mpreinit(mp *m) {
   797	}
   798	
   799	//go:nosplit
   800	func msigsave(mp *m) {
   801	}
   802	
   803	//go:nosplit
   804	func msigrestore(sigmask sigset) {
   805	}
   806	
   807	//go:nosplit
   808	//go:nowritebarrierrec
   809	func clearSignalHandlers() {
   810	}
   811	
   812	//go:nosplit
   813	func sigblock() {
   814	}
   815	
   816	// Called to initialize a new m (including the bootstrap m).
   817	// Called on the new thread, cannot allocate memory.
   818	func minit() {
   819		var thandle uintptr
   820		stdcall7(_DuplicateHandle, currentProcess, currentThread, currentProcess, uintptr(unsafe.Pointer(&thandle)), 0, 0, _DUPLICATE_SAME_ACCESS)
   821		atomic.Storeuintptr(&getg().m.thread, thandle)
   822	
   823		// Query the true stack base from the OS. Currently we're
   824		// running on a small assumed stack.
   825		var mbi memoryBasicInformation
   826		res := stdcall3(_VirtualQuery, uintptr(unsafe.Pointer(&mbi)), uintptr(unsafe.Pointer(&mbi)), unsafe.Sizeof(mbi))
   827		if res == 0 {
   828			print("runtime: VirtualQuery failed; errno=", getlasterror(), "\n")
   829			throw("VirtualQuery for stack base failed")
   830		}
   831		// The system leaves an 8K PAGE_GUARD region at the bottom of
   832		// the stack (in theory VirtualQuery isn't supposed to include
   833		// that, but it does). Add an additional 8K of slop for
   834		// calling C functions that don't have stack checks and for
   835		// lastcontinuehandler. We shouldn't be anywhere near this
   836		// bound anyway.
   837		base := mbi.allocationBase + 16<<10
   838		// Sanity check the stack bounds.
   839		g0 := getg()
   840		if base > g0.stack.hi || g0.stack.hi-base > 64<<20 {
   841			print("runtime: g0 stack [", hex(base), ",", hex(g0.stack.hi), ")\n")
   842			throw("bad g0 stack")
   843		}
   844		g0.stack.lo = base
   845		g0.stackguard0 = g0.stack.lo + _StackGuard
   846		g0.stackguard1 = g0.stackguard0
   847		// Sanity check the SP.
   848		stackcheck()
   849	}
   850	
   851	// Called from dropm to undo the effect of an minit.
   852	//go:nosplit
   853	func unminit() {
   854		tp := &getg().m.thread
   855		stdcall1(_CloseHandle, *tp)
   856		*tp = 0
   857	}
   858	
   859	// Calling stdcall on os stack.
   860	// May run during STW, so write barriers are not allowed.
   861	//go:nowritebarrier
   862	//go:nosplit
   863	func stdcall(fn stdFunction) uintptr {
   864		gp := getg()
   865		mp := gp.m
   866		mp.libcall.fn = uintptr(unsafe.Pointer(fn))
   867		resetLibcall := false
   868		if mp.profilehz != 0 && mp.libcallsp == 0 {
   869			// leave pc/sp for cpu profiler
   870			mp.libcallg.set(gp)
   871			mp.libcallpc = getcallerpc()
   872			// sp must be the last, because once async cpu profiler finds
   873			// all three values to be non-zero, it will use them
   874			mp.libcallsp = getcallersp()
   875			resetLibcall = true // See comment in sys_darwin.go:libcCall
   876		}
   877		asmcgocall(asmstdcallAddr, unsafe.Pointer(&mp.libcall))
   878		if resetLibcall {
   879			mp.libcallsp = 0
   880		}
   881		return mp.libcall.r1
   882	}
   883	
   884	//go:nosplit
   885	func stdcall0(fn stdFunction) uintptr {
   886		mp := getg().m
   887		mp.libcall.n = 0
   888		mp.libcall.args = uintptr(noescape(unsafe.Pointer(&fn))) // it's unused but must be non-nil, otherwise crashes
   889		return stdcall(fn)
   890	}
   891	
   892	//go:nosplit
   893	func stdcall1(fn stdFunction, a0 uintptr) uintptr {
   894		mp := getg().m
   895		mp.libcall.n = 1
   896		mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
   897		return stdcall(fn)
   898	}
   899	
   900	//go:nosplit
   901	func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr {
   902		mp := getg().m
   903		mp.libcall.n = 2
   904		mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
   905		return stdcall(fn)
   906	}
   907	
   908	//go:nosplit
   909	func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr {
   910		mp := getg().m
   911		mp.libcall.n = 3
   912		mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
   913		return stdcall(fn)
   914	}
   915	
   916	//go:nosplit
   917	func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr {
   918		mp := getg().m
   919		mp.libcall.n = 4
   920		mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
   921		return stdcall(fn)
   922	}
   923	
   924	//go:nosplit
   925	func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr {
   926		mp := getg().m
   927		mp.libcall.n = 5
   928		mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
   929		return stdcall(fn)
   930	}
   931	
   932	//go:nosplit
   933	func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr {
   934		mp := getg().m
   935		mp.libcall.n = 6
   936		mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
   937		return stdcall(fn)
   938	}
   939	
   940	//go:nosplit
   941	func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
   942		mp := getg().m
   943		mp.libcall.n = 7
   944		mp.libcall.args = uintptr(noescape(unsafe.Pointer(&a0)))
   945		return stdcall(fn)
   946	}
   947	
   948	// in sys_windows_386.s and sys_windows_amd64.s
   949	func onosstack(fn unsafe.Pointer, arg uint32)
   950	func usleep2(usec uint32)
   951	func switchtothread()
   952	
   953	var usleep2Addr unsafe.Pointer
   954	var switchtothreadAddr unsafe.Pointer
   955	
   956	//go:nosplit
   957	func osyield() {
   958		onosstack(switchtothreadAddr, 0)
   959	}
   960	
   961	//go:nosplit
   962	func usleep(us uint32) {
   963		// Have 1us units; want 100ns units.
   964		onosstack(usleep2Addr, 10*us)
   965	}
   966	
   967	func ctrlhandler1(_type uint32) uint32 {
   968		var s uint32
   969	
   970		switch _type {
   971		case _CTRL_C_EVENT, _CTRL_BREAK_EVENT:
   972			s = _SIGINT
   973		default:
   974			return 0
   975		}
   976	
   977		if sigsend(s) {
   978			return 1
   979		}
   980		exit(2) // SIGINT, SIGTERM, etc
   981		return 0
   982	}
   983	
   984	// in sys_windows_386.s and sys_windows_amd64.s
   985	func profileloop()
   986	
   987	// called from zcallback_windows_*.s to sys_windows_*.s
   988	func callbackasm1()
   989	
   990	var profiletimer uintptr
   991	
   992	func profilem(mp *m, thread uintptr) {
   993		var r *context
   994		rbuf := make([]byte, unsafe.Sizeof(*r)+15)
   995	
   996		// align Context to 16 bytes
   997		r = (*context)(unsafe.Pointer((uintptr(unsafe.Pointer(&rbuf[15]))) &^ 15))
   998		r.contextflags = _CONTEXT_CONTROL
   999		stdcall2(_GetThreadContext, thread, uintptr(unsafe.Pointer(r)))
  1000	
  1001		var gp *g
  1002		switch GOARCH {
  1003		default:
  1004			panic("unsupported architecture")
  1005		case "arm":
  1006			tls := &mp.tls[0]
  1007			gp = **((***g)(unsafe.Pointer(tls)))
  1008		case "386", "amd64":
  1009			tls := &mp.tls[0]
  1010			gp = *((**g)(unsafe.Pointer(tls)))
  1011		}
  1012	
  1013		sigprof(r.ip(), r.sp(), r.lr(), gp, mp)
  1014	}
  1015	
  1016	func profileloop1(param uintptr) uint32 {
  1017		stdcall2(_SetThreadPriority, currentThread, _THREAD_PRIORITY_HIGHEST)
  1018	
  1019		for {
  1020			stdcall2(_WaitForSingleObject, profiletimer, _INFINITE)
  1021			first := (*m)(atomic.Loadp(unsafe.Pointer(&allm)))
  1022			for mp := first; mp != nil; mp = mp.alllink {
  1023				thread := atomic.Loaduintptr(&mp.thread)
  1024				// Do not profile threads blocked on Notes,
  1025				// this includes idle worker threads,
  1026				// idle timer thread, idle heap scavenger, etc.
  1027				if thread == 0 || mp.profilehz == 0 || mp.blocked {
  1028					continue
  1029				}
  1030				// mp may exit between the load above and the
  1031				// SuspendThread, so be careful.
  1032				if int32(stdcall1(_SuspendThread, thread)) == -1 {
  1033					// The thread no longer exists.
  1034					continue
  1035				}
  1036				if mp.profilehz != 0 && !mp.blocked {
  1037					// Pass the thread handle in case mp
  1038					// was in the process of shutting down.
  1039					profilem(mp, thread)
  1040				}
  1041				stdcall1(_ResumeThread, thread)
  1042			}
  1043		}
  1044	}
  1045	
  1046	func setProcessCPUProfiler(hz int32) {
  1047		if profiletimer == 0 {
  1048			timer := stdcall3(_CreateWaitableTimerA, 0, 0, 0)
  1049			atomic.Storeuintptr(&profiletimer, timer)
  1050			thread := stdcall6(_CreateThread, 0, 0, funcPC(profileloop), 0, 0, 0)
  1051			stdcall2(_SetThreadPriority, thread, _THREAD_PRIORITY_HIGHEST)
  1052			stdcall1(_CloseHandle, thread)
  1053		}
  1054	}
  1055	
  1056	func setThreadCPUProfiler(hz int32) {
  1057		ms := int32(0)
  1058		due := ^int64(^uint64(1 << 63))
  1059		if hz > 0 {
  1060			ms = 1000 / hz
  1061			if ms == 0 {
  1062				ms = 1
  1063			}
  1064			due = int64(ms) * -10000
  1065		}
  1066		stdcall6(_SetWaitableTimer, profiletimer, uintptr(unsafe.Pointer(&due)), uintptr(ms), 0, 0, 0)
  1067		atomic.Store((*uint32)(unsafe.Pointer(&getg().m.profilehz)), uint32(hz))
  1068	}
  1069	

View as plain text