aboutsummaryrefslogtreecommitdiff
path: root/src/internal
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2021-05-26 12:55:16 -0700
committerDamien Neil <dneil@google.com>2021-08-16 23:54:32 +0000
commitd9349175ad13ab228d3224c4bff8e3e1b2936b42 (patch)
treeb451b8f1f7a1821aeba031ccd58a0bf00eb10a89 /src/internal
parent8ff16c19909e5aecf51c6b993cba36ea51791f34 (diff)
downloadgo-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.go52
-rw-r--r--src/internal/poll/fd_windows.go10
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.