Skip to content

Commit f8242c7

Browse files
committed
runtime: ensure time.Sleep(d) sleeps at least d
Account for the sleep queue base time in the computation of the wakeup time. Tested with the following program on pico2. func main() { go func() { for i := range 60 { const delay = 20 * time.Millisecond before := time.Now() time.Sleep(delay) if d := time.Since(before); true || d < delay { log.Println(i, "actual", d, "delay", delay) } } }() time.Sleep(500 * time.Millisecond) log.Println("******** done sleeping ********") select {} } Without this change, the program would print lines such as: 17 actual 15.494ms delay 20ms 18 actual 15.49ms delay 20ms 19 actual 15.585ms delay 20ms 20 actual 15.493ms delay 20ms 21 actual 15.494ms delay 20ms 22 actual 15.487ms delay 20ms 23 actual 15.498ms delay 20ms ******** done sleeping ******** 24 actual 15.548ms delay 20ms 25 actual 20.011ms delay 20ms 26 actual 20.01ms delay 20ms 27 actual 20.011ms delay 20ms 28 actual 20.015ms delay 20ms Note that while more than one sleeping goroutine is in the timer queue, the sleep duration is 5ms short.
1 parent df1d639 commit f8242c7

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

src/runtime/scheduler_cooperative.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,14 @@ func addSleepTask(t *task.Task, duration timeUnit) {
7777
panic("runtime: addSleepTask: expected next task to be nil")
7878
}
7979
}
80-
t.Data = uint64(duration)
8180
now := ticks()
8281
if sleepQueue == nil {
8382
scheduleLog(" -> sleep new queue")
8483

8584
// set new base time
8685
sleepQueueBaseTime = now
8786
}
87+
t.Data = uint64(duration + (now - sleepQueueBaseTime))
8888

8989
// Add to sleep queue.
9090
q := &sleepQueue

0 commit comments

Comments
 (0)