//go:cgo_import_dynamic runtime._WriteConsoleW WriteConsoleW%5 "kernel32.dll"
//go:cgo_import_dynamic runtime._WriteFile WriteFile%5 "kernel32.dll"
//go:cgo_import_dynamic runtime._timeBeginPeriod timeBeginPeriod%1 "winmm.dll"
+//go:cgo_import_dynamic runtime._timeEndPeriod timeEndPeriod%1 "winmm.dll"
type stdFunction unsafe.Pointer
_WriteConsoleW,
_WriteFile,
_timeBeginPeriod,
+ _timeEndPeriod,
_ stdFunction
// Following syscalls are only available on some Windows PCs.
var timeBeginPeriodRetValue uint32
+// osRelax is called by the scheduler when transitioning to and from
+// all Ps being idle.
+//
+// On Windows, it adjusts the system-wide timer resolution. Go needs a
+// high resolution timer while running and there's little extra cost
+// if we're already using the CPU, but if all Ps are idle there's no
+// need to consume extra power to drive the high-res timer.
+func osRelax(relax bool) uint32 {
+ if relax {
+ return uint32(stdcall1(_timeEndPeriod, 1))
+ } else {
+ return uint32(stdcall1(_timeBeginPeriod, 1))
+ }
+}
+
func osinit() {
asmstdcallAddr = unsafe.Pointer(funcPC(asmstdcall))
usleep2Addr = unsafe.Pointer(funcPC(usleep2))
stdcall2(_SetConsoleCtrlHandler, funcPC(ctrlhandler), 1)
- timeBeginPeriodRetValue = uint32(stdcall1(_timeBeginPeriod, 1))
+ timeBeginPeriodRetValue = osRelax(false)
ncpu = getproccount()
if scavengelimit < forcegcperiod {
maxsleep = scavengelimit / 2
}
+ osRelax(true)
notetsleep(&sched.sysmonnote, maxsleep)
+ osRelax(false)
lock(&sched.lock)
atomic.Store(&sched.sysmonwait, 0)
noteclear(&sched.sysmonnote)
--- /dev/null
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !windows
+
+package runtime
+
+// osRelax is called by the scheduler when transitioning to and from
+// all Ps being idle.
+func osRelax(relax bool) {}