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.
|
||||
func (fd *FD) Write(p []byte) (int, error) {
|
||||
if err := fd.writeLock(); err != nil {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue