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.
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
diff --git a/src/pkg/runtime/proc_test.go b/src/pkg/runtime/proc_test.go
index 927bd7b..1f727da 100644
--- a/src/pkg/runtime/proc_test.go
+++ b/src/pkg/runtime/proc_test.go
@@ -46,6 +46,36 @@
 	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)