]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: eliminate the redundant for loop in runqget()
authorAndy Pan <panjf2000@gmail.com>
Thu, 6 May 2021 01:04:03 +0000 (09:04 +0800)
committerAustin Clements <austin@google.com>
Tue, 31 Aug 2021 13:54:19 +0000 (13:54 +0000)
Change-Id: If9b283bbef3ff12a64d34b07491aee3396852f05
Reviewed-on: https://go-review.googlesource.com/c/go/+/317509
Reviewed-by: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Trust: Keith Randall <khr@golang.org>

src/runtime/proc.go

index 55023e3f9f0bb6acb74b353350bf3f6792b5cf8b..197441dfa75441734468eea8a2ef315fa975e46d 100644 (file)
@@ -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 {