]> Cypherpunks repositories - gostls13.git/commitdiff
net: remove the alloc from ReadMsgUDPAddrPort
authorJosh Bleecher Snyder <josharian@gmail.com>
Wed, 3 Nov 2021 21:42:52 +0000 (14:42 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 4 Nov 2021 21:52:06 +0000 (21:52 +0000)
name                          old time/op    new time/op    delta
ReadWriteMsgUDPAddrPort-8       4.95µs ± 5%    4.55µs ± 1%    -7.96%  (p=0.016 n=5+4)

name                          old alloc/op   new alloc/op   delta
ReadWriteMsgUDPAddrPort-8        32.0B ± 0%      0.0B       -100.00%  (p=0.008 n=5+5)

name                          old allocs/op  new allocs/op  delta
ReadWriteMsgUDPAddrPort-8         1.00 ± 0%      0.00       -100.00%  (p=0.008 n=5+5)

Change-Id: Ib968c6f2968926ec9a364dd52063cd0d7c29b10c
Reviewed-on: https://go-review.googlesource.com/c/go/+/360862
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
src/internal/poll/fd_unix.go
src/internal/poll/fd_windows.go
src/internal/syscall/unix/net.go
src/internal/syscall/unix/net_js.go
src/net/fd_posix.go
src/net/net_fake.go
src/net/udpsock_posix.go
src/syscall/syscall_unix.go

index b090e5b6bdc1546dc62cea755125dfa6edee5259..45d4ce07b2c6cc58804efa8ebb6720cd549389f6 100644 (file)
@@ -311,6 +311,60 @@ func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.S
        }
 }
 
+// ReadMsgInet4 is ReadMsg, but specialized for syscall.SockaddrInet4.
+func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
+       if err := fd.readLock(); err != nil {
+               return 0, 0, 0, err
+       }
+       defer fd.readUnlock()
+       if err := fd.pd.prepareRead(fd.isFile); err != nil {
+               return 0, 0, 0, err
+       }
+       for {
+               n, oobn, sysflags, err := unix.RecvmsgInet4(fd.Sysfd, p, oob, flags, sa4)
+               if err != nil {
+                       if err == syscall.EINTR {
+                               continue
+                       }
+                       // TODO(dfc) should n and oobn be set to 0
+                       if err == syscall.EAGAIN && fd.pd.pollable() {
+                               if err = fd.pd.waitRead(fd.isFile); err == nil {
+                                       continue
+                               }
+                       }
+               }
+               err = fd.eofError(n, err)
+               return n, oobn, sysflags, err
+       }
+}
+
+// ReadMsgInet6 is ReadMsg, but specialized for syscall.SockaddrInet6.
+func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
+       if err := fd.readLock(); err != nil {
+               return 0, 0, 0, err
+       }
+       defer fd.readUnlock()
+       if err := fd.pd.prepareRead(fd.isFile); err != nil {
+               return 0, 0, 0, err
+       }
+       for {
+               n, oobn, sysflags, err := unix.RecvmsgInet6(fd.Sysfd, p, oob, flags, sa6)
+               if err != nil {
+                       if err == syscall.EINTR {
+                               continue
+                       }
+                       // TODO(dfc) should n and oobn be set to 0
+                       if err == syscall.EAGAIN && fd.pd.pollable() {
+                               if err = fd.pd.waitRead(fd.isFile); err == nil {
+                                       continue
+                               }
+                       }
+               }
+               err = fd.eofError(n, err)
+               return n, oobn, sysflags, err
+       }
+}
+
 // Write implements io.Writer.
 func (fd *FD) Write(p []byte) (int, error) {
        if err := fd.writeLock(); err != nil {
index f8fc4de75df882c1992ce7ea7a91b57d58e77b7d..4dd5986efd30397a989beb724c318d7c7a288966 100644 (file)
@@ -620,10 +620,7 @@ func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error)
        if err != nil {
                return n, err
        }
-       sa, _ := o.rsa.Sockaddr()
-       if sa != nil {
-               *sa4 = *(sa.(*syscall.SockaddrInet4))
-       }
+       rawToSockaddrInet4(o.rsa, sa4)
        return n, err
 }
 
@@ -652,10 +649,7 @@ func (fd *FD) ReadFromInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error)
        if err != nil {
                return n, err
        }
-       sa, _ := o.rsa.Sockaddr()
-       if sa != nil {
-               *sa6 = *(sa.(*syscall.SockaddrInet6))
-       }
+       rawToSockaddrInet6(o.rsa, sa6)
        return n, err
 }
 
@@ -1149,6 +1143,21 @@ func sockaddrInet6ToRaw(sa syscall.SockaddrInet6) (unsafe.Pointer, int32) {
        return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw))
 }
 
+func rawToSockaddrInet4(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet4) {
+       pp := (*syscall.RawSockaddrInet4)(unsafe.Pointer(rsa))
+       p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+       sa.Port = int(p[0])<<8 + int(p[1])
+       sa.Addr = pp.Addr
+}
+
+func rawToSockaddrInet6(rsa *syscall.RawSockaddrAny, sa *syscall.SockaddrInet6) {
+       pp := (*syscall.RawSockaddrInet6)(unsafe.Pointer(rsa))
+       p := (*[2]byte)(unsafe.Pointer(&pp.Port))
+       sa.Port = int(p[0])<<8 + int(p[1])
+       sa.ZoneId = pp.Scope_id
+       sa.Addr = pp.Addr
+}
+
 func sockaddrToRaw(sa syscall.Sockaddr) (unsafe.Pointer, int32, error) {
        switch sa := sa.(type) {
        case *syscall.SockaddrInet4:
@@ -1190,6 +1199,60 @@ func (fd *FD) ReadMsg(p []byte, oob []byte, flags int) (int, int, int, syscall.S
        return n, int(o.msg.Control.Len), int(o.msg.Flags), sa, err
 }
 
+// ReadMsgInet4 is ReadMsg, but specialized to return a syscall.SockaddrInet4.
+func (fd *FD) ReadMsgInet4(p []byte, oob []byte, flags int, sa4 *syscall.SockaddrInet4) (int, int, int, error) {
+       if err := fd.readLock(); err != nil {
+               return 0, 0, 0, err
+       }
+       defer fd.readUnlock()
+
+       if len(p) > maxRW {
+               p = p[:maxRW]
+       }
+
+       o := &fd.rop
+       o.InitMsg(p, oob)
+       o.rsa = new(syscall.RawSockaddrAny)
+       o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
+       o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
+       o.msg.Flags = uint32(flags)
+       n, err := execIO(o, func(o *operation) error {
+               return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
+       })
+       err = fd.eofError(n, err)
+       if err == nil {
+               rawToSockaddrInet4(o.rsa, sa4)
+       }
+       return n, int(o.msg.Control.Len), int(o.msg.Flags), err
+}
+
+// ReadMsgInet6 is ReadMsg, but specialized to return a syscall.SockaddrInet6.
+func (fd *FD) ReadMsgInet6(p []byte, oob []byte, flags int, sa6 *syscall.SockaddrInet6) (int, int, int, error) {
+       if err := fd.readLock(); err != nil {
+               return 0, 0, 0, err
+       }
+       defer fd.readUnlock()
+
+       if len(p) > maxRW {
+               p = p[:maxRW]
+       }
+
+       o := &fd.rop
+       o.InitMsg(p, oob)
+       o.rsa = new(syscall.RawSockaddrAny)
+       o.msg.Name = (syscall.Pointer)(unsafe.Pointer(o.rsa))
+       o.msg.Namelen = int32(unsafe.Sizeof(*o.rsa))
+       o.msg.Flags = uint32(flags)
+       n, err := execIO(o, func(o *operation) error {
+               return windows.WSARecvMsg(o.fd.Sysfd, &o.msg, &o.qty, &o.o, nil)
+       })
+       err = fd.eofError(n, err)
+       if err == nil {
+               rawToSockaddrInet6(o.rsa, sa6)
+       }
+       return n, int(o.msg.Control.Len), int(o.msg.Flags), err
+}
+
 // WriteMsg wraps the WSASendMsg network call.
 func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
        if len(p) > maxRW {
index 71e50f54c35cf1fe01bd3ea3de5d27de52d20733..87ce89b57fcd01bde02350f8b641084dc85baf47 100644 (file)
@@ -34,3 +34,11 @@ func SendmsgNInet4(fd int, p, oob []byte, to syscall.SockaddrInet4, flags int) (
 //go:linkname SendmsgNInet6 syscall.sendmsgNInet6
 //go:noescape
 func SendmsgNInet6(fd int, p, oob []byte, to syscall.SockaddrInet6, flags int) (n int, err error)
+
+//go:linkname RecvmsgInet4 syscall.recvmsgInet4
+//go:noescape
+func RecvmsgInet4(fd int, p, oob []byte, flags int, from *syscall.SockaddrInet4) (n, oobn int, recvflags int, err error)
+
+//go:linkname RecvmsgInet6 syscall.recvmsgInet6
+//go:noescape
+func RecvmsgInet6(fd int, p, oob []byte, flags int, from *syscall.SockaddrInet6) (n, oobn int, recvflags int, err error)
index 35bc687b5845030ac1c749336e04c1998431f458..defc3f6fb2b44dd32e17537b962b916dad651081 100644 (file)
@@ -34,3 +34,11 @@ func SendmsgNInet4(fd int, p, oob []byte, to syscall.SockaddrInet4, flags int) (
 func SendmsgNInet6(fd int, p, oob []byte, to syscall.SockaddrInet6, flags int) (n int, err error) {
        return 0, syscall.ENOSYS
 }
+
+func RecvmsgInet4(fd int, p, oob []byte, flags int, from *syscall.SockaddrInet4) (n, oobn int, recvflags int, err error) {
+       return 0, 0, 0, syscall.ENOSYS
+}
+
+func RecvmsgInet6(fd int, p, oob []byte, flags int, from *syscall.SockaddrInet6) (n, oobn int, recvflags int, err error) {
+       return 0, 0, 0, syscall.ENOSYS
+}
index edcef1f2e18e3773db7a831230d6185d743a81f4..d12dbeebd21542ce0ba3fb7332a4d6a6aa445b67 100644 (file)
@@ -80,6 +80,18 @@ func (fd *netFD) readMsg(p []byte, oob []byte, flags int) (n, oobn, retflags int
        return n, oobn, retflags, sa, wrapSyscallError(readMsgSyscallName, err)
 }
 
+func (fd *netFD) readMsgInet4(p []byte, oob []byte, flags int, sa *syscall.SockaddrInet4) (n, oobn, retflags int, err error) {
+       n, oobn, retflags, err = fd.pfd.ReadMsgInet4(p, oob, flags, sa)
+       runtime.KeepAlive(fd)
+       return n, oobn, retflags, wrapSyscallError(readMsgSyscallName, err)
+}
+
+func (fd *netFD) readMsgInet6(p []byte, oob []byte, flags int, sa *syscall.SockaddrInet6) (n, oobn, retflags int, err error) {
+       n, oobn, retflags, err = fd.pfd.ReadMsgInet6(p, oob, flags, sa)
+       runtime.KeepAlive(fd)
+       return n, oobn, retflags, wrapSyscallError(readMsgSyscallName, err)
+}
+
 func (fd *netFD) Write(p []byte) (nn int, err error) {
        nn, err = fd.pfd.Write(p)
        runtime.KeepAlive(fd)
index 2ade9f777455e094fc7b4f890566fe9f194b5ecc..8da9d15bb25cd3a3574fb89c5cf619c4e4c5638c 100644 (file)
@@ -279,6 +279,14 @@ func (fd *netFD) readMsg(p []byte, oob []byte, flags int) (n, oobn, retflags int
        return 0, 0, 0, nil, syscall.ENOSYS
 }
 
+func (fd *netFD) readMsgInet4(p []byte, oob []byte, flags int, sa *syscall.SockaddrInet4) (n, oobn, retflags int, err error) {
+       return 0, 0, 0, syscall.ENOSYS
+}
+
+func (fd *netFD) readMsgInet6(p []byte, oob []byte, flags int, sa *syscall.SockaddrInet6) (n, oobn, retflags int, err error) {
+       return 0, 0, 0, syscall.ENOSYS
+}
+
 func (fd *netFD) writeMsgInet4(p []byte, oob []byte, sa syscall.SockaddrInet4) (n int, oobn int, err error) {
        return 0, 0, syscall.ENOSYS
 }
index 468afbc4dc69433209b7968ca67e49407b14f4c0..2bf6568a95c13dd88191d8281dbc175e68d705cb 100644 (file)
@@ -95,13 +95,15 @@ func (c *UDPConn) readFromAddrPort(b []byte) (n int, addr netip.AddrPort, err er
 }
 
 func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr netip.AddrPort, err error) {
-       var sa syscall.Sockaddr
-       n, oobn, flags, sa, err = c.fd.readMsg(b, oob, 0)
-       switch sa := sa.(type) {
-       case *syscall.SockaddrInet4:
+       switch c.fd.family {
+       case syscall.AF_INET:
+               var sa syscall.SockaddrInet4
+               n, oobn, flags, err = c.fd.readMsgInet4(b, oob, 0, &sa)
                ip := netip.AddrFrom4(sa.Addr)
                addr = netip.AddrPortFrom(ip, uint16(sa.Port))
-       case *syscall.SockaddrInet6:
+       case syscall.AF_INET6:
+               var sa syscall.SockaddrInet6
+               n, oobn, flags, err = c.fd.readMsgInet6(b, oob, 0, &sa)
                ip := netip.AddrFrom16(sa.Addr).WithZone(zoneCache.name(int(sa.ZoneId)))
                addr = netip.AddrPortFrom(ip, uint16(sa.Port))
        }
index 8692a657947c4365d5088c814d6a71f1c006d875..56d3cad1d0695d7ff33c94856ca1b69bdb09fe8b 100644 (file)
@@ -324,6 +324,33 @@ func recvfromInet6(fd int, p []byte, flags int, from *SockaddrInet6) (n int, err
        return
 }
 
+func recvmsgInet4(fd int, p, oob []byte, flags int, from *SockaddrInet4) (n, oobn int, recvflags int, err error) {
+       var rsa RawSockaddrAny
+       n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
+       if err != nil {
+               return
+       }
+       pp := (*RawSockaddrInet4)(unsafe.Pointer(&rsa))
+       port := (*[2]byte)(unsafe.Pointer(&pp.Port))
+       from.Port = int(port[0])<<8 + int(port[1])
+       from.Addr = pp.Addr
+       return
+}
+
+func recvmsgInet6(fd int, p, oob []byte, flags int, from *SockaddrInet6) (n, oobn int, recvflags int, err error) {
+       var rsa RawSockaddrAny
+       n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
+       if err != nil {
+               return
+       }
+       pp := (*RawSockaddrInet6)(unsafe.Pointer(&rsa))
+       port := (*[2]byte)(unsafe.Pointer(&pp.Port))
+       from.Port = int(port[0])<<8 + int(port[1])
+       from.ZoneId = pp.Scope_id
+       from.Addr = pp.Addr
+       return
+}
+
 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
        var rsa RawSockaddrAny
        n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)