From 3920d6f2085559ae262d651b00bf8b29f953580a Mon Sep 17 00:00:00 2001 From: Andy Pan Date: Thu, 6 May 2021 09:04:03 +0800 Subject: [PATCH] runtime: eliminate the redundant for loop in runqget() Change-Id: If9b283bbef3ff12a64d34b07491aee3396852f05 Reviewed-on: https://go-review.googlesource.com/c/go/+/317509 Reviewed-by: Austin Clements Run-TryBot: Austin Clements TryBot-Result: Go Bot Trust: Keith Randall --- src/runtime/proc.go | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 55023e3f9f0..197441dfa75 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -5994,14 +5994,12 @@ func runqputbatch(pp *p, q *gQueue, qsize int) { // Executed only by the owner P. func runqget(_p_ *p) (gp *g, inheritTime bool) { // If there's a runnext, it's the next G to run. - for { - next := _p_.runnext - if next == 0 { - break - } - if _p_.runnext.cas(next, 0) { - return next.ptr(), true - } + next := _p_.runnext + // If the runnext is non-0 and the CAS fails, it could only have been stolen by another P, + // because other Ps can race to set runnext to 0, but only the current P can set it to non-0. + // Hence, there's no need to retry this CAS if it falls. + if next != 0 && _p_.runnext.cas(next, 0) { + return next.ptr(), true } for {