Skip to content

Instantly share code, notes, and snippets.

@prashantv
Created April 23, 2021 04:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save prashantv/fdd710e270244efa23ba7a3fcb45b088 to your computer and use it in GitHub Desktop.
Save prashantv/fdd710e270244efa23ba7a3fcb45b088 to your computer and use it in GitHub Desktop.
runtime timers stop firing when GOMAXPROCS is reduced
package main
import (
"fmt"
"runtime"
"sync"
"time"
)
func main() {
for i := 0; i < 20; i++ {
fmt.Println("attempt", i)
run(10, 100)
}
}
func run(gomaxprocs, goroutines int) {
runtime.GOMAXPROCS(gomaxprocs)
var wg sync.WaitGroup
// Crate tickers in background goroutines (spread them across Ps)
tickers := make([]*time.Ticker, goroutines)
for i := 0; i < goroutines; i++ {
wg.Add(1)
go func(i int) {
t := time.NewTicker(time.Millisecond)
tickers[i] = t
wg.Done()
}(i)
}
// Reduce GOMAXPROCS to try and trigger the bug.
for i := runtime.GOMAXPROCS(0); i > 0; i-- {
runtime.Gosched()
runtime.GOMAXPROCS(i)
}
runtime.GOMAXPROCS(1)
// Wait for all tickers to be scheduled
wg.Wait()
// Verify all tickers are working
for i := 0; i < 10; i++ {
for ti, t := range tickers {
select {
case <-t.C:
case <-time.After(10 * time.Second):
fmt.Printf("========= Likely bug =======\ntimer %v timed out after 10s of waiting %v\n", ti, i)
waitStart := time.Now()
<-t.C
fmt.Println("Timer eventually fired after", time.Since(waitStart))
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment