Skip to content

Commit 83c8140

Browse files
committed
time: avoid broken fix for buggy TestOverflowRuntimeTimer
The test requires that timerproc runs, but busy loops and starves the scheduler so that, with high probability, timerproc doesn't run. Avoid the issue by expecting the test to succeed; if not, a major outside timeout will kill it and let us know. As you can see from the diffs, there have been several attempts to fix this with chicanery, but none has worked. Don't bother trying any more. Fixes #8136. LGTM=rsc R=rsc, josharian CC=golang-codereviews https://golang.org/cl/105140043
1 parent e46be90 commit 83c8140

File tree

2 files changed

+12
-45
lines changed

2 files changed

+12
-45
lines changed

src/pkg/time/internal_test.go

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@
44

55
package time
66

7-
import (
8-
"errors"
9-
"runtime"
10-
)
11-
127
func init() {
138
// force US/Pacific for time zone tests
149
ForceUSPacificForTesting()
@@ -24,7 +19,7 @@ func empty(now int64, arg interface{}) {}
2419
//
2520
// This test has to be in internal_test.go since it fiddles with
2621
// unexported data structures.
27-
func CheckRuntimeTimerOverflow() error {
22+
func CheckRuntimeTimerOverflow() {
2823
// We manually create a runtimeTimer to bypass the overflow
2924
// detection logic in NewTimer: we're testing the underlying
3025
// runtime.addtimer function.
@@ -35,17 +30,7 @@ func CheckRuntimeTimerOverflow() error {
3530
}
3631
startTimer(r)
3732

38-
timeout := 100 * Millisecond
39-
switch runtime.GOOS {
40-
// Allow more time for gobuilder to succeed.
41-
case "windows":
42-
timeout = Second
43-
case "plan9":
44-
// TODO(0intro): We don't know why it is needed.
45-
timeout = 3 * Second
46-
}
47-
48-
// Start a goroutine that should send on t.C before the timeout.
33+
// Start a goroutine that should send on t.C right away.
4934
t := NewTimer(1)
5035

5136
defer func() {
@@ -64,29 +49,11 @@ func CheckRuntimeTimerOverflow() error {
6449
startTimer(r)
6550
}()
6651

67-
// Try to receive from t.C before the timeout. It will succeed
68-
// iff the previous sleep was able to finish. We're forced to
69-
// spin and yield after trying to receive since we can't start
70-
// any more timers (they might hang due to the same bug we're
71-
// now testing).
72-
stop := Now().Add(timeout)
73-
for {
74-
select {
75-
case <-t.C:
76-
return nil // It worked!
77-
default:
78-
if Now().After(stop) {
79-
return errors.New("runtime timer stuck: overflow in addtimer")
80-
}
81-
// Issue 6874. This test previously called runtime.Gosched to try to yield
82-
// to the goroutine servicing t, however the scheduler has a bias towards the
83-
// previously running goroutine in an idle system. Combined with high load due
84-
// to all CPUs busy running tests t's goroutine could be delayed beyond the
85-
// timeout window.
86-
//
87-
// Calling runtime.GC() reduces the worst case lantency for scheduling t by 20x
88-
// under the current Go 1.3 scheduler.
89-
runtime.GC()
90-
}
91-
}
52+
// If the test fails, we will hang here until the timeout in the testing package
53+
// fires, which is 10 minutes. It would be nice to catch the problem sooner,
54+
// but there is no reliable way to guarantee that timerproc schedules without
55+
// doing something involving timerproc itself. Previous failed attempts have
56+
// tried calling runtime.Gosched and runtime.GC, but neither is reliable.
57+
// So we fall back to hope: We hope we don't hang here.
58+
<-t.C
9259
}

src/pkg/time/sleep_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ func TestOverflowRuntimeTimer(t *testing.T) {
387387
if testing.Short() {
388388
t.Skip("skipping in short mode, see issue 6874")
389389
}
390-
if err := CheckRuntimeTimerOverflow(); err != nil {
391-
t.Fatalf(err.Error())
392-
}
390+
// This may hang forever if timers are broken. See comment near
391+
// the end of CheckRuntimeTimerOverflow in internal_test.go.
392+
CheckRuntimeTimerOverflow()
393393
}

0 commit comments

Comments
 (0)