var timeBeginPeriodRetValue uint32
-// osRelaxDelay indicates that sysmon should wait for 60 ms of
-// idleness before osRelaxing. Since osRelaxing may reduce timer
-// resolution to 15.6 ms, this keeps timer error under roughly 1 part
-// in 4.
-const osRelaxDelay = 60 * 1e6
+// osRelaxMinNS indicates that sysmon shouldn't osRelax if the next
+// timer is less than 60 ms from now. Since osRelaxing may reduce
+// timer resolution to 15.6 ms, this keeps timer error under roughly 1
+// part in 4.
+const osRelaxMinNS = 60 * 1e6
// osRelax is called by the scheduler when transitioning to and from
// all Ps being idle.
if scavengelimit < forcegcperiod {
maxsleep = scavengelimit / 2
}
- if osRelaxDelay > 0 {
- // Wait before osRelaxing in
- // case something happens soon.
- sleep1 := int64(osRelaxDelay)
- if sleep1 > maxsleep {
- sleep1 = maxsleep
- }
- if notetsleep(&sched.sysmonnote, sleep1) {
- maxsleep = 0
- } else {
- maxsleep -= sleep1
+ shouldRelax := true
+ if osRelaxMinNS > 0 {
+ lock(&timers.lock)
+ if timers.sleeping {
+ now := nanotime()
+ next := timers.sleepUntil
+ if next-now < osRelaxMinNS {
+ shouldRelax = false
+ }
}
+ unlock(&timers.lock)
}
- if maxsleep > 0 {
+ if shouldRelax {
osRelax(true)
- notetsleep(&sched.sysmonnote, maxsleep)
+ }
+ notetsleep(&sched.sysmonnote, maxsleep)
+ if shouldRelax {
osRelax(false)
}
lock(&sched.lock)
package runtime
-// osRelaxDelay is the number of nanoseconds of idleness to tolerate
-// before performing an osRelax. Since osRelax may reduce the
+// osRelaxMinNS is the number of nanoseconds of idleness to tolerate
+// without performing an osRelax. Since osRelax may reduce the
// precision of timers, this should be enough larger than the relaxed
// timer precision to keep the timer error acceptable.
-const osRelaxDelay = 0
+const osRelaxMinNS = 0
// osRelax is called by the scheduler when transitioning to and from
// all Ps being idle.
created bool
sleeping bool
rescheduling bool
+ sleepUntil int64
waitnote note
t []*timer
}
}
// At least one timer pending. Sleep until then.
timers.sleeping = true
+ timers.sleepUntil = now + delta
noteclear(&timers.waitnote)
unlock(&timers.lock)
notetsleepg(&timers.waitnote, delta)