]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: ensure forward progress of runtime.Gosched() for locked goroutines
authorDmitriy Vyukov <dvyukov@google.com>
Wed, 20 Feb 2013 08:13:04 +0000 (12:13 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Wed, 20 Feb 2013 08:13:04 +0000 (12:13 +0400)
The removed code leads to the situation when M executes the same locked G again
and again.
This is https://golang.org/cl/7310096 but with return instead of break
in the nested switch.
Fixes #4820.

R=golang-dev, alex.brainman, rsc
CC=golang-dev
https://golang.org/cl/7304102

src/pkg/runtime/proc.c
src/pkg/runtime/proc_test.go

index f8ddf9b47e5dd0fe79e752c091a85435611dc66d..5c60cddf9babb0fbe1e54e3f16b0766f5c842c97 100644 (file)
@@ -397,14 +397,6 @@ canaddmcpu(void)
 static void
 gput(G *gp)
 {
-       M *mp;
-
-       // If g is wired, hand it off directly.
-       if((mp = gp->lockedm) != nil && canaddmcpu()) {
-               mnextg(mp, gp);
-               return;
-       }
-
        // If g is the idle goroutine for an m, hand it off.
        if(gp->idlem != nil) {
                if(gp->idlem->idleg != nil) {
index 927bd7b816a7d36706c3f3176b18560fcff40ca8..1f727da073c343aa3bb0f794405bf75d742fb6d2 100644 (file)
@@ -46,6 +46,36 @@ func TestStopTheWorldDeadlock(t *testing.T) {
        runtime.GOMAXPROCS(maxprocs)
 }
 
+func TestYieldProgress(t *testing.T) {
+       testYieldProgress(t, false)
+}
+
+func TestYieldLockedProgress(t *testing.T) {
+       testYieldProgress(t, true)
+}
+
+func testYieldProgress(t *testing.T, locked bool) {
+       c := make(chan bool)
+       cack := make(chan bool)
+       go func() {
+               if locked {
+                       runtime.LockOSThread()
+               }
+               for {
+                       select {
+                       case <-c:
+                               cack <- true
+                               return
+                       default:
+                               runtime.Gosched()
+                       }
+               }
+       }()
+       time.Sleep(10 * time.Millisecond)
+       c <- true
+       <-cack
+}
+
 func TestYieldLocked(t *testing.T) {
        const N = 10
        c := make(chan bool)