Skip to content

Commit

Permalink
runtime: move timer recheck after GC recheck
Browse files Browse the repository at this point in the history
When rechecking for work after transitioning from a spinning to
non-spinning M, checking timers before GC isn't useful. That is, if
there is GC work available, it will run immediately and the updated
pollUntil is unused.

Move this check to just before netpoll, where pollUntil is used. While
this technically improves efficiency in the (rare) case that we find
GC work in this block, the primary motivation is simply to improve
clarity by moving the update closer to use.

For #43997

Change-Id: Ibc7fb308ac4a582875c200659c9e272121a89f3b
Reviewed-on: https://go-review.googlesource.com/c/go/+/308654
Trust: Michael Pratt <mpratt@google.com>
Trust: Michael Knyszek <mknyszek@google.com>
Run-TryBot: Michael Pratt <mpratt@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
  • Loading branch information
prattmic committed Apr 21, 2021
1 parent 381252f commit 4d56576
Showing 1 changed file with 9 additions and 7 deletions.
16 changes: 9 additions & 7 deletions src/runtime/proc.go
Expand Up @@ -2810,13 +2810,7 @@ top:
goto top
}

// Similar to above, check for timer creation or expiry concurrently with
// transitioning from spinning to non-spinning. Note that we cannot use
// checkTimers here because it calls adjusttimers which may need to allocate
// memory, and that isn't allowed when we don't have an active P.
pollUntil = checkTimersNoP(allpSnapshot, timerpMaskSnapshot, pollUntil)

// Finally, check for idle-priority GC work.
// Check for idle-priority GC work again.
_p_, gp = checkIdleGCNoP()
if _p_ != nil {
acquirep(_p_)
Expand All @@ -2834,6 +2828,14 @@ top:
return gp, false
}

// Finally, check for timer creation or expiry concurrently with
// transitioning from spinning to non-spinning.
//
// Note that we cannot use checkTimers here because it calls
// adjusttimers which may need to allocate memory, and that isn't
// allowed when we don't have an active P.
pollUntil = checkTimersNoP(allpSnapshot, timerpMaskSnapshot, pollUntil)

// Poll network until next timer.
if netpollinited() && (atomic.Load(&netpollWaiters) > 0 || pollUntil != 0) && atomic.Xchg64(&sched.lastpoll, 0) != 0 {
atomic.Store64(&sched.pollUntil, uint64(pollUntil))
Expand Down

0 comments on commit 4d56576

Please sign in to comment.