Commit a0efca84 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

time: fix deadlock in Sleep(0)

See time/sleep_test.go for repro.

R=golang-dev, r, rsc
CC=golang-dev, patrick.allen.higgins
https://golang.org/cl/6250072
parent 93fe8c0c
...@@ -61,8 +61,11 @@ runtime·tsleep(int64 ns) ...@@ -61,8 +61,11 @@ runtime·tsleep(int64 ns)
{ {
Timer t; Timer t;
if(ns <= 0) if(ns <= 0) {
g->status = Grunning;
g->waitreason = nil;
return; return;
}
t.when = runtime·nanotime() + ns; t.when = runtime·nanotime() + ns;
t.period = 0; t.period = 0;
......
...@@ -223,3 +223,25 @@ func TestTimerStopStress(t *testing.T) { ...@@ -223,3 +223,25 @@ func TestTimerStopStress(t *testing.T) {
} }
Sleep(3 * Second) Sleep(3 * Second)
} }
func TestSleepZeroDeadlock(t *testing.T) {
// Sleep(0) used to hang, the sequence of events was as follows.
// Sleep(0) sets G's status to Gwaiting, but then immediately returns leaving the status.
// Then the goroutine calls e.g. new and falls down into the scheduler due to pending GC.
// After the GC nobody wakes up the goroutine from Gwaiting status.
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
c := make(chan bool)
go func() {
for i := 0; i < 100; i++ {
runtime.GC()
}
c <- true
}()
for i := 0; i < 100; i++ {
Sleep(0)
tmp := make(chan bool, 1)
tmp <- true
<-tmp
}
<-c
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment