mirror of
https://github.com/golang/go
synced 2024-11-24 07:50:13 -07:00
net: remove the alloc from WriteMsgUDPAddrPort
name old time/op new time/op delta ReadWriteMsgUDPAddrPort-8 5.12µs ± 8% 4.59µs ± 3% -10.19% (p=0.000 n=10+9) name old alloc/op new alloc/op delta ReadWriteMsgUDPAddrPort-8 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=10+10) name old allocs/op new allocs/op delta ReadWriteMsgUDPAddrPort-8 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=10+10) Change-Id: Idf540b2f9f8035660305a0ab1cfc3e162569db63 Reviewed-on: https://go-review.googlesource.com/c/go/+/361257 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
156abe5122
commit
bfd74fd422
@ -485,6 +485,58 @@ func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, err
|
||||
}
|
||||
}
|
||||
|
||||
// WriteMsgInet4 is WriteMsg specialized for syscall.SockaddrInet4.
|
||||
func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa syscall.SockaddrInet4) (int, int, error) {
|
||||
if err := fd.writeLock(); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
defer fd.writeUnlock()
|
||||
if err := fd.pd.prepareWrite(fd.isFile); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
for {
|
||||
n, err := unix.SendmsgNInet4(fd.Sysfd, p, oob, sa, 0)
|
||||
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 n, 0, err
|
||||
}
|
||||
return n, len(oob), err
|
||||
}
|
||||
}
|
||||
|
||||
// WriteMsgInet6 is WriteMsg specialized for syscall.SockaddrInet6.
|
||||
func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa syscall.SockaddrInet6) (int, int, error) {
|
||||
if err := fd.writeLock(); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
defer fd.writeUnlock()
|
||||
if err := fd.pd.prepareWrite(fd.isFile); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
for {
|
||||
n, err := unix.SendmsgNInet6(fd.Sysfd, p, oob, sa, 0)
|
||||
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 n, 0, err
|
||||
}
|
||||
return n, len(oob), err
|
||||
}
|
||||
}
|
||||
|
||||
// Accept wraps the accept network call.
|
||||
func (fd *FD) Accept() (int, syscall.Sockaddr, string, error) {
|
||||
if err := fd.readLock(); err != nil {
|
||||
|
@ -1128,25 +1128,35 @@ func (fd *FD) RawWrite(f func(uintptr) bool) error {
|
||||
return syscall.EWINDOWS
|
||||
}
|
||||
|
||||
func sockaddrInet4ToRaw(sa syscall.SockaddrInet4) (unsafe.Pointer, int32) {
|
||||
var raw syscall.RawSockaddrInet4
|
||||
raw.Family = syscall.AF_INET
|
||||
p := (*[2]byte)(unsafe.Pointer(&raw.Port))
|
||||
p[0] = byte(sa.Port >> 8)
|
||||
p[1] = byte(sa.Port)
|
||||
raw.Addr = sa.Addr
|
||||
return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw))
|
||||
}
|
||||
|
||||
func sockaddrInet6ToRaw(sa syscall.SockaddrInet6) (unsafe.Pointer, int32) {
|
||||
var raw syscall.RawSockaddrInet6
|
||||
raw.Family = syscall.AF_INET6
|
||||
p := (*[2]byte)(unsafe.Pointer(&raw.Port))
|
||||
p[0] = byte(sa.Port >> 8)
|
||||
p[1] = byte(sa.Port)
|
||||
raw.Scope_id = sa.ZoneId
|
||||
raw.Addr = sa.Addr
|
||||
return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw))
|
||||
}
|
||||
|
||||
func sockaddrToRaw(sa syscall.Sockaddr) (unsafe.Pointer, int32, error) {
|
||||
switch sa := sa.(type) {
|
||||
case *syscall.SockaddrInet4:
|
||||
var raw syscall.RawSockaddrInet4
|
||||
raw.Family = syscall.AF_INET
|
||||
p := (*[2]byte)(unsafe.Pointer(&raw.Port))
|
||||
p[0] = byte(sa.Port >> 8)
|
||||
p[1] = byte(sa.Port)
|
||||
raw.Addr = sa.Addr
|
||||
return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw)), nil
|
||||
ptr, sz := sockaddrInet4ToRaw(*sa)
|
||||
return ptr, sz, nil
|
||||
case *syscall.SockaddrInet6:
|
||||
var raw syscall.RawSockaddrInet6
|
||||
raw.Family = syscall.AF_INET6
|
||||
p := (*[2]byte)(unsafe.Pointer(&raw.Port))
|
||||
p[0] = byte(sa.Port >> 8)
|
||||
p[1] = byte(sa.Port)
|
||||
raw.Scope_id = sa.ZoneId
|
||||
raw.Addr = sa.Addr
|
||||
return unsafe.Pointer(&raw), int32(unsafe.Sizeof(raw)), nil
|
||||
ptr, sz := sockaddrInet6ToRaw(*sa)
|
||||
return ptr, sz, nil
|
||||
default:
|
||||
return nil, 0, syscall.EWINDOWS
|
||||
}
|
||||
@ -1206,3 +1216,47 @@ func (fd *FD) WriteMsg(p []byte, oob []byte, sa syscall.Sockaddr) (int, int, err
|
||||
})
|
||||
return n, int(o.msg.Control.Len), err
|
||||
}
|
||||
|
||||
// WriteMsgInet4 is WriteMsg specialized for syscall.SockaddrInet4.
|
||||
func (fd *FD) WriteMsgInet4(p []byte, oob []byte, sa syscall.SockaddrInet4) (int, int, error) {
|
||||
if len(p) > maxRW {
|
||||
return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
|
||||
}
|
||||
|
||||
if err := fd.writeLock(); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
defer fd.writeUnlock()
|
||||
|
||||
o := &fd.wop
|
||||
o.InitMsg(p, oob)
|
||||
rsa, len := sockaddrInet4ToRaw(sa)
|
||||
o.msg.Name = (syscall.Pointer)(rsa)
|
||||
o.msg.Namelen = len
|
||||
n, err := execIO(o, func(o *operation) error {
|
||||
return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
|
||||
})
|
||||
return n, int(o.msg.Control.Len), err
|
||||
}
|
||||
|
||||
// WriteMsgInet6 is WriteMsg specialized for syscall.SockaddrInet6.
|
||||
func (fd *FD) WriteMsgInet6(p []byte, oob []byte, sa syscall.SockaddrInet6) (int, int, error) {
|
||||
if len(p) > maxRW {
|
||||
return 0, 0, errors.New("packet is too large (only 1GB is allowed)")
|
||||
}
|
||||
|
||||
if err := fd.writeLock(); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
defer fd.writeUnlock()
|
||||
|
||||
o := &fd.wop
|
||||
o.InitMsg(p, oob)
|
||||
rsa, len := sockaddrInet6ToRaw(sa)
|
||||
o.msg.Name = (syscall.Pointer)(rsa)
|
||||
o.msg.Namelen = len
|
||||
n, err := execIO(o, func(o *operation) error {
|
||||
return windows.WSASendMsg(o.fd.Sysfd, &o.msg, 0, &o.qty, &o.o, nil)
|
||||
})
|
||||
return n, int(o.msg.Control.Len), err
|
||||
}
|
||||
|
@ -26,3 +26,11 @@ func SendtoInet4(fd int, p []byte, flags int, to syscall.SockaddrInet4) (err err
|
||||
//go:linkname SendtoInet6 syscall.sendtoInet6
|
||||
//go:noescape
|
||||
func SendtoInet6(fd int, p []byte, flags int, to syscall.SockaddrInet6) (err error)
|
||||
|
||||
//go:linkname SendmsgNInet4 syscall.sendmsgNInet4
|
||||
//go:noescape
|
||||
func SendmsgNInet4(fd int, p, oob []byte, to syscall.SockaddrInet4, flags int) (n int, err error)
|
||||
|
||||
//go:linkname SendmsgNInet6 syscall.sendmsgNInet6
|
||||
//go:noescape
|
||||
func SendmsgNInet6(fd int, p, oob []byte, to syscall.SockaddrInet6, flags int) (n int, err error)
|
||||
|
@ -26,3 +26,11 @@ func SendtoInet4(fd int, p []byte, flags int, to syscall.SockaddrInet4) (err err
|
||||
func SendtoInet6(fd int, p []byte, flags int, to syscall.SockaddrInet6) (err error) {
|
||||
return syscall.ENOSYS
|
||||
}
|
||||
|
||||
func SendmsgNInet4(fd int, p, oob []byte, to syscall.SockaddrInet4, flags int) (n int, err error) {
|
||||
return 0, syscall.ENOSYS
|
||||
}
|
||||
|
||||
func SendmsgNInet6(fd int, p, oob []byte, to syscall.SockaddrInet6, flags int) (n int, err error) {
|
||||
return 0, syscall.ENOSYS
|
||||
}
|
||||
|
@ -110,6 +110,18 @@ func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oob
|
||||
return n, oobn, wrapSyscallError(writeMsgSyscallName, err)
|
||||
}
|
||||
|
||||
func (fd *netFD) writeMsgInet4(p []byte, oob []byte, sa syscall.SockaddrInet4) (n int, oobn int, err error) {
|
||||
n, oobn, err = fd.pfd.WriteMsgInet4(p, oob, sa)
|
||||
runtime.KeepAlive(fd)
|
||||
return n, oobn, wrapSyscallError(writeMsgSyscallName, err)
|
||||
}
|
||||
|
||||
func (fd *netFD) writeMsgInet6(p []byte, oob []byte, sa syscall.SockaddrInet6) (n int, oobn int, err error) {
|
||||
n, oobn, err = fd.pfd.WriteMsgInet6(p, oob, sa)
|
||||
runtime.KeepAlive(fd)
|
||||
return n, oobn, wrapSyscallError(writeMsgSyscallName, err)
|
||||
}
|
||||
|
||||
func (fd *netFD) SetDeadline(t time.Time) error {
|
||||
return fd.pfd.SetDeadline(t)
|
||||
}
|
||||
|
@ -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) writeMsgInet4(p []byte, oob []byte, sa syscall.SockaddrInet4) (n int, oobn int, err error) {
|
||||
return 0, 0, syscall.ENOSYS
|
||||
}
|
||||
|
||||
func (fd *netFD) writeMsgInet6(p []byte, oob []byte, sa syscall.SockaddrInet6) (n int, oobn int, err error) {
|
||||
return 0, 0, syscall.ENOSYS
|
||||
}
|
||||
|
||||
func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
|
||||
return 0, syscall.ENOSYS
|
||||
}
|
||||
|
@ -188,15 +188,13 @@ func (c *UDPConn) writeMsgAddrPort(b, oob []byte, addr netip.AddrPort) (n, oobn
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
// TODO: Implement writeMsgInet4 to avoid allocation converting sa to an interface.
|
||||
return c.fd.writeMsg(b, oob, &sa)
|
||||
return c.fd.writeMsgInet4(b, oob, sa)
|
||||
case syscall.AF_INET6:
|
||||
sa, err := addrPortToSockaddrInet6(addr)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
// TODO: Implement writeMsgInet6 to avoid allocation converting sa to an interface.
|
||||
return c.fd.writeMsg(b, oob, &sa)
|
||||
return c.fd.writeMsgInet6(b, oob, sa)
|
||||
default:
|
||||
return 0, 0, &AddrError{Err: "invalid address family", Addr: addr.Addr().String()}
|
||||
}
|
||||
|
@ -351,6 +351,22 @@ func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error)
|
||||
return sendmsgN(fd, p, oob, ptr, salen, flags)
|
||||
}
|
||||
|
||||
func sendmsgNInet4(fd int, p, oob []byte, to SockaddrInet4, flags int) (n int, err error) {
|
||||
ptr, salen, err := to.sockaddr()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return sendmsgN(fd, p, oob, ptr, salen, flags)
|
||||
}
|
||||
|
||||
func sendmsgNInet6(fd int, p, oob []byte, to SockaddrInet6, flags int) (n int, err error) {
|
||||
ptr, salen, err := to.sockaddr()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return sendmsgN(fd, p, oob, ptr, salen, flags)
|
||||
}
|
||||
|
||||
func sendtoInet4(fd int, p []byte, flags int, to SockaddrInet4) (err error) {
|
||||
ptr, n, err := to.sockaddr()
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user