diff options
author | Josh Bleecher Snyder <josharian@gmail.com> | 2021-05-26 12:55:16 -0700 |
---|---|---|
committer | Damien Neil <dneil@google.com> | 2021-08-16 23:54:32 +0000 |
commit | d9349175ad13ab228d3224c4bff8e3e1b2936b42 (patch) | |
tree | b451b8f1f7a1821aeba031ccd58a0bf00eb10a89 /src/internal | |
parent | 8ff16c19909e5aecf51c6b993cba36ea51791f34 (diff) | |
download | go-d9349175ad13ab228d3224c4bff8e3e1b2936b42.tar.gz go-d9349175ad13ab228d3224c4bff8e3e1b2936b42.zip |
net: remove allocation from UDPConn.WriteTo
Duplicate some code to avoid an interface.
name old time/op new time/op delta
WriteToReadFromUDP-8 6.38µs ±20% 5.59µs ±10% -12.38% (p=0.001 n=10+9)
name old alloc/op new alloc/op delta
WriteToReadFromUDP-8 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=10+10)
name old allocs/op new allocs/op delta
WriteToReadFromUDP-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10)
Windows is temporarily stubbed out.
Updates #43451
Change-Id: Ied15ff92268c652cf445836e0446025eaeb60cc9
Reviewed-on: https://go-review.googlesource.com/c/go/+/331489
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Diffstat (limited to 'src/internal')
-rw-r--r-- | src/internal/poll/fd_unix.go | 52 | ||||
-rw-r--r-- | src/internal/poll/fd_windows.go | 10 |
2 files changed, 62 insertions, 0 deletions
diff --git a/src/internal/poll/fd_unix.go b/src/internal/poll/fd_unix.go index 3b17cd22b0..51d15f6abc 100644 --- a/src/internal/poll/fd_unix.go +++ b/src/internal/poll/fd_unix.go @@ -327,6 +327,58 @@ func (fd *FD) Pwrite(p []byte, off int64) (int, error) { } } +// WriteToInet4 wraps the sendto network call for IPv4 addresses. +func (fd *FD) WriteToInet4(p []byte, sa syscall.SockaddrInet4) (int, error) { + if err := fd.writeLock(); err != nil { + return 0, err + } + defer fd.writeUnlock() + if err := fd.pd.prepareWrite(fd.isFile); err != nil { + return 0, err + } + for { + err := syscall.SendtoInet4(fd.Sysfd, p, 0, sa) + if err == syscall.EINTR { + continue + } + if err == syscall.EAGAIN && fd.pd.pollable() { + if err = fd.pd.waitWrite(fd.isFile); err == nil { + continue + } + } + if err != nil { + return 0, err + } + return len(p), nil + } +} + +// WriteToInet6 wraps the sendto network call for IPv6 addresses. +func (fd *FD) WriteToInet6(p []byte, sa syscall.SockaddrInet6) (int, error) { + if err := fd.writeLock(); err != nil { + return 0, err + } + defer fd.writeUnlock() + if err := fd.pd.prepareWrite(fd.isFile); err != nil { + return 0, err + } + for { + err := syscall.SendtoInet6(fd.Sysfd, p, 0, sa) + if err == syscall.EINTR { + continue + } + if err == syscall.EAGAIN && fd.pd.pollable() { + if err = fd.pd.waitWrite(fd.isFile); err == nil { + continue + } + } + if err != nil { + return 0, err + } + return len(p), nil + } +} + // WriteTo wraps the sendto network call. func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) { if err := fd.writeLock(); err != nil { diff --git a/src/internal/poll/fd_windows.go b/src/internal/poll/fd_windows.go index 4a5169527c..3dada32985 100644 --- a/src/internal/poll/fd_windows.go +++ b/src/internal/poll/fd_windows.go @@ -791,6 +791,16 @@ func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) { return ntotal, nil } +// WriteTo wraps the sendto network call for IPv4. +func (fd *FD) WriteToInet4(buf []byte, sa syscall.SockaddrInet4) (int, error) { + return fd.WriteTo(buf, &sa) +} + +// WriteTo wraps the sendto network call for IPv6. +func (fd *FD) WriteToInet6(buf []byte, sa syscall.SockaddrInet6) (int, error) { + return fd.WriteTo(buf, &sa) +} + // Call ConnectEx. This doesn't need any locking, since it is only // called when the descriptor is first created. This is here rather // than in the net package so that it can use fd.wop. |