diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2018-10-31 17:03:35 +0100 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2018-11-02 12:49:16 +0000 |
commit | a86f549703c107c8b4d83d8e7527521c9e215d9a (patch) | |
tree | 07dc006883bd7b4cf9d2b0581e11109ee28b6403 /src/runtime/netpoll.go | |
parent | 86d375498fa377c7d81c5b93750e8dce2389500e (diff) | |
download | go-a86f549703c107c8b4d83d8e7527521c9e215d9a.tar.gz go-a86f549703c107c8b4d83d8e7527521c9e215d9a.zip |
runtime: add and use modtimer in netpoll
Currently when netpoll deadline is incrementally prolonged,
we delete and re-add timer each time.
Add modtimer function that does both and use it when we need
to modify an existing netpoll timer to avoid unnecessary lock/unlock.
TCP4OneShotTimeout-6 17.2µs ± 0% 17.0µs ± 0% -0.82% (p=0.008 n=5+5)
SetReadDeadline-6 274ns ± 2% 261ns ± 0% -4.89% (p=0.008 n=5+5)
Update #25729
Change-Id: I08b89dbbc1785dd180e967a37b0aa23b0c4613a8
Reviewed-on: https://go-review.googlesource.com/c/146339
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/runtime/netpoll.go')
-rw-r--r-- | src/runtime/netpoll.go | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/src/runtime/netpoll.go b/src/runtime/netpoll.go index 00701665f1..34e7c902eb 100644 --- a/src/runtime/netpoll.go +++ b/src/runtime/netpoll.go @@ -211,21 +211,13 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) { pd.wd = d } combo := pd.rd > 0 && pd.rd == pd.wd - // Reset current timers if necessary. - if pd.rt.f != nil && (pd.rd != rd0 || combo != combo0) { - pd.rseq++ // invalidate current timers - deltimer(&pd.rt) - pd.rt.f = nil - } - if pd.wt.f != nil && (pd.wd != wd0 || combo != combo0) { - pd.wseq++ // invalidate current timers - deltimer(&pd.wt) - pd.wt.f = nil - } - // Setup new timers. + rtf := netpollReadDeadline if combo { - if pd.rt.f == nil { - pd.rt.f = netpollDeadline + rtf = netpollDeadline + } + if pd.rt.f == nil { + if pd.rd > 0 { + pd.rt.f = rtf pd.rt.when = pd.rd // Copy current seq into the timer arg. // Timer func will check the seq against current descriptor seq, @@ -234,21 +226,31 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) { pd.rt.seq = pd.rseq addtimer(&pd.rt) } - } else { - if pd.rd > 0 && pd.rt.f == nil { - pd.rt.f = netpollReadDeadline - pd.rt.when = pd.rd - pd.rt.arg = pd - pd.rt.seq = pd.rseq - addtimer(&pd.rt) + } else if pd.rd != rd0 || combo != combo0 { + pd.rseq++ // invalidate current timers + if pd.rd > 0 { + modtimer(&pd.rt, pd.rd, 0, rtf, pd, pd.rseq) + } else { + deltimer(&pd.rt) + pd.rt.f = nil } - if pd.wd > 0 && pd.wt.f == nil { + } + if pd.wt.f == nil { + if pd.wd > 0 && !combo { pd.wt.f = netpollWriteDeadline pd.wt.when = pd.wd pd.wt.arg = pd pd.wt.seq = pd.wseq addtimer(&pd.wt) } + } else if pd.wd != wd0 || combo != combo0 { + pd.wseq++ // invalidate current timers + if pd.wd > 0 && !combo { + modtimer(&pd.wt, pd.wd, 0, netpollWriteDeadline, pd, pd.wseq) + } else { + deltimer(&pd.wt) + pd.wt.f = nil + } } // If we set the new deadline in the past, unblock currently pending IO if any. var rg, wg *g |