From f87b7f67b232db252a527dbc000533a27ccb8cd2 Mon Sep 17 00:00:00 2001 From: Dmitriy Vyukov Date: Fri, 15 Feb 2013 22:22:13 +0400 Subject: [PATCH] runtime: ensure forward progress of runtime.Gosched() for locked goroutines The removed code leads to the situation when M executes the same locked G again and again. Fixes #4820. R=golang-dev, rsc CC=golang-dev https://golang.org/cl/7310096 --- src/pkg/runtime/proc.c | 8 -------- src/pkg/runtime/proc_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c index 1d3ac595ae7..8a6fa378f2d 100644 --- a/src/pkg/runtime/proc.c +++ b/src/pkg/runtime/proc.c @@ -389,14 +389,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) { diff --git a/src/pkg/runtime/proc_test.go b/src/pkg/runtime/proc_test.go index 927bd7b816a..b68599a4961 100644 --- a/src/pkg/runtime/proc_test.go +++ b/src/pkg/runtime/proc_test.go @@ -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 + break + default: + runtime.Gosched() + } + } + }() + time.Sleep(10 * time.Millisecond) + c <- true + <-cack +} + func TestYieldLocked(t *testing.T) { const N = 10 c := make(chan bool)