mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
net: remove the alloc from ReadMsgUDPAddrPort
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>
This commit is contained in:
parent
bfd74fd422
commit
37634eeff9
8 changed files with 195 additions and 13 deletions
|
|
@ -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.
|
// Write implements io.Writer.
|
||||||
func (fd *FD) Write(p []byte) (int, error) {
|
func (fd *FD) Write(p []byte) (int, error) {
|
||||||
if err := fd.writeLock(); err != nil {
|
if err := fd.writeLock(); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -620,10 +620,7 @@ func (fd *FD) ReadFromInet4(buf []byte, sa4 *syscall.SockaddrInet4) (int, error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
sa, _ := o.rsa.Sockaddr()
|
rawToSockaddrInet4(o.rsa, sa4)
|
||||||
if sa != nil {
|
|
||||||
*sa4 = *(sa.(*syscall.SockaddrInet4))
|
|
||||||
}
|
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -652,10 +649,7 @@ func (fd *FD) ReadFromInet6(buf []byte, sa6 *syscall.SockaddrInet6) (int, error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
sa, _ := o.rsa.Sockaddr()
|
rawToSockaddrInet6(o.rsa, sa6)
|
||||||
if sa != nil {
|
|
||||||
*sa6 = *(sa.(*syscall.SockaddrInet6))
|
|
||||||
}
|
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1149,6 +1143,21 @@ func sockaddrInet6ToRaw(sa syscall.SockaddrInet6) (unsafe.Pointer, int32) {
|
||||||
return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw))
|
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) {
|
func sockaddrToRaw(sa syscall.Sockaddr) (unsafe.Pointer, int32, error) {
|
||||||
switch sa := sa.(type) {
|
switch sa := sa.(type) {
|
||||||
case *syscall.SockaddrInet4:
|
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
|
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.
|
// WriteMsg wraps the WSASendMsg network call.
|
||||||
func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
|
func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, error) {
|
||||||
if len(p) > maxRW {
|
if len(p) > maxRW {
|
||||||
|
|
|
||||||
|
|
@ -34,3 +34,11 @@ func SendmsgNInet4(fd int, p, oob []byte, to syscall.SockaddrInet4, flags int) (
|
||||||
//go:linkname SendmsgNInet6 syscall.sendmsgNInet6
|
//go:linkname SendmsgNInet6 syscall.sendmsgNInet6
|
||||||
//go:noescape
|
//go:noescape
|
||||||
func SendmsgNInet6(fd int, p, oob []byte, to syscall.SockaddrInet6, flags int) (n int, err error)
|
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)
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
func SendmsgNInet6(fd int, p, oob []byte, to syscall.SockaddrInet6, flags int) (n int, err error) {
|
||||||
return 0, syscall.ENOSYS
|
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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
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) {
|
func (fd *netFD) Write(p []byte) (nn int, err error) {
|
||||||
nn, err = fd.pfd.Write(p)
|
nn, err = fd.pfd.Write(p)
|
||||||
runtime.KeepAlive(fd)
|
runtime.KeepAlive(fd)
|
||||||
|
|
|
||||||
|
|
@ -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
|
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) {
|
func (fd *netFD) writeMsgInet4(p []byte, oob []byte, sa syscall.SockaddrInet4) (n int, oobn int, err error) {
|
||||||
return 0, 0, syscall.ENOSYS
|
return 0, 0, syscall.ENOSYS
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
func (c *UDPConn) readMsg(b, oob []byte) (n, oobn, flags int, addr netip.AddrPort, err error) {
|
||||||
var sa syscall.Sockaddr
|
switch c.fd.family {
|
||||||
n, oobn, flags, sa, err = c.fd.readMsg(b, oob, 0)
|
case syscall.AF_INET:
|
||||||
switch sa := sa.(type) {
|
var sa syscall.SockaddrInet4
|
||||||
case *syscall.SockaddrInet4:
|
n, oobn, flags, err = c.fd.readMsgInet4(b, oob, 0, &sa)
|
||||||
ip := netip.AddrFrom4(sa.Addr)
|
ip := netip.AddrFrom4(sa.Addr)
|
||||||
addr = netip.AddrPortFrom(ip, uint16(sa.Port))
|
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)))
|
ip := netip.AddrFrom16(sa.Addr).WithZone(zoneCache.name(int(sa.ZoneId)))
|
||||||
addr = netip.AddrPortFrom(ip, uint16(sa.Port))
|
addr = netip.AddrPortFrom(ip, uint16(sa.Port))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -324,6 +324,33 @@ func recvfromInet6(fd int, p []byte, flags int, from *SockaddrInet6) (n int, err
|
||||||
return
|
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) {
|
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
|
||||||
var rsa RawSockaddrAny
|
var rsa RawSockaddrAny
|
||||||
n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
|
n, oobn, recvflags, err = recvmsgRaw(fd, p, oob, flags, &rsa)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue