]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: avoid runtimeNano call on a common netpoll path
authorDmitry Vyukov <dvyukov@google.com>
Wed, 31 Oct 2018 14:07:57 +0000 (15:07 +0100)
committerDmitry Vyukov <dvyukov@google.com>
Fri, 2 Nov 2018 12:55:58 +0000 (12:55 +0000)
runtimeNano is slower than nanotime, so pass the duration
to runtime_pollSetDeadline as is. netpoll can add nanotime itself.
Arguably a bit simpler because, say, a negative duration
clearly represents already expired timer, no need to compare to
nanotime again.
This may also fix an obscure corner case when a deadline in past
which happens to be nanotime 0 is confused with no deadline at all,
which are radically different things.
Also don't compute any durations and times if Time is zero
(currently we first compute everything and then reset d back to 0,
which is wasteful).

name                  old time/op  new time/op  delta
TCP4OneShotTimeout-6  17.1µs ± 0%  17.0µs ± 0%     ~     (p=0.421 n=5+5)
SetReadDeadline-6      230ns ± 0%   205ns ± 1%  -10.63%  (p=0.008 n=5+5)

Change-Id: I2aad699270289a5b9ead68f5e44ec4ec6d96baa0
Reviewed-on: https://go-review.googlesource.com/c/146344
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>

src/internal/poll/fd_poll_runtime.go
src/runtime/netpoll.go

index a48e62eefa44370a6861fc6a752822fdb6ce4ca9..f4540a60f689bd83aa769bc2d02c27a5c415c05d 100644 (file)
@@ -136,15 +136,12 @@ func (fd *FD) SetWriteDeadline(t time.Time) error {
 }
 
 func setDeadlineImpl(fd *FD, t time.Time, mode int) error {
-       diff := int64(time.Until(t))
-       d := runtimeNano() + diff
-       if d <= 0 && diff > 0 {
-               // If the user has a deadline in the future, but the delay calculation
-               // overflows, then set the deadline to the maximum possible value.
-               d = 1<<63 - 1
-       }
-       if t.IsZero() {
-               d = 0
+       var d int64
+       if !t.IsZero() {
+               d = int64(time.Until(t))
+               if d == 0 {
+                       d = -1 // don't confuse deadline right now with no deadline
+               }
        }
        if err := fd.incref(); err != nil {
                return err
index f914844cdf5084d777ffe13ce58d9db7928eedf8..7e6e93d6c37f3711d4c5b942524e506781c51764 100644 (file)
@@ -201,8 +201,13 @@ func poll_runtime_pollSetDeadline(pd *pollDesc, d int64, mode int) {
        }
        rd0, wd0 := pd.rd, pd.wd
        combo0 := rd0 > 0 && rd0 == wd0
-       if d != 0 && d <= nanotime() {
-               d = -1
+       if d > 0 {
+               d += nanotime()
+               if d <= 0 {
+                       // If the user has a deadline in the future, but the delay calculation
+                       // overflows, then set the deadline to the maximum possible value.
+                       d = 1<<63 - 1
+               }
        }
        if mode == 'r' || mode == 'r'+'w' {
                pd.rd = d