aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2013-02-15 22:22:13 +0400
committerDmitriy Vyukov <dvyukov@google.com>2013-02-15 22:22:13 +0400
commitf87b7f67b232db252a527dbc000533a27ccb8cd2 (patch)
tree059b70e75c66e48a8c2929da6474be3aba3cdabb /src/pkg/runtime
parentd3d89ae7d21d8253626aebf212a63d670561f659 (diff)
downloadgo-f87b7f67b232db252a527dbc000533a27ccb8cd2.tar.xz
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
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/proc.c8
-rw-r--r--src/pkg/runtime/proc_test.go30
2 files changed, 30 insertions, 8 deletions
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
index 1d3ac595ae..8a6fa378f2 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 927bd7b816..b68599a496 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)