Commit a9280fa2 authored by Dmitry Vyukov's avatar Dmitry Vyukov

runtime: don't wake timeproc needlessly

It's not always necessary to wake timerproc even if we add
a new timer to the top of the heap. Since we don't wake and
reset timerproc when we remove timers, it still can be sleeping
with shorter timeout. It such case it's more profitable to let it
sleep and then update timeout when it wakes on its own rather than
proactively wake it, let it update timeout and go to sleep again.

name                  old time/op  new time/op  delta
TCP4OneShotTimeout-6  18.6µs ± 1%  17.2µs ± 0%   -7.66%  (p=0.008 n=5+5)
SetReadDeadline-6      562ns ± 5%   319ns ± 1%  -43.27%  (p=0.008 n=5+5)

Update #25729

Change-Id: Iec8eacb8563dbc574a82358b3bac7ac479c16826
Reviewed-on: https://go-review.googlesource.com/c/146337Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 7f998453
...@@ -796,3 +796,34 @@ func TestCopyPipeIntoTCP(t *testing.T) { ...@@ -796,3 +796,34 @@ func TestCopyPipeIntoTCP(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
} }
func BenchmarkSetReadDeadline(b *testing.B) {
ln, err := newLocalListener("tcp")
if err != nil {
b.Fatal(err)
}
defer ln.Close()
var serv Conn
done := make(chan error)
go func() {
var err error
serv, err = ln.Accept()
done <- err
}()
c, err := Dial("tcp", ln.Addr().String())
if err != nil {
b.Fatal(err)
}
defer c.Close()
if err := <-done; err != nil {
b.Fatal(err)
}
defer serv.Close()
c.SetWriteDeadline(time.Now().Add(2 * time.Hour))
deadline := time.Now().Add(time.Hour)
b.ResetTimer()
for i := 0; i < b.N; i++ {
c.SetReadDeadline(deadline)
deadline = deadline.Add(1)
}
}
...@@ -156,7 +156,7 @@ func (tb *timersBucket) addtimerLocked(t *timer) bool { ...@@ -156,7 +156,7 @@ func (tb *timersBucket) addtimerLocked(t *timer) bool {
} }
if t.i == 0 { if t.i == 0 {
// siftup moved to top: new earliest deadline. // siftup moved to top: new earliest deadline.
if tb.sleeping { if tb.sleeping && tb.sleepUntil > t.when {
tb.sleeping = false tb.sleeping = false
notewakeup(&tb.waitnote) notewakeup(&tb.waitnote)
} }
...@@ -164,11 +164,11 @@ func (tb *timersBucket) addtimerLocked(t *timer) bool { ...@@ -164,11 +164,11 @@ func (tb *timersBucket) addtimerLocked(t *timer) bool {
tb.rescheduling = false tb.rescheduling = false
goready(tb.gp, 0) goready(tb.gp, 0)
} }
}
if !tb.created { if !tb.created {
tb.created = true tb.created = true
go timerproc(tb) go timerproc(tb)
} }
}
return true return true
} }
......
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