mirror of
https://github.com/golang/go
synced 2024-11-26 16:57:14 -07:00
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>
This commit is contained in:
parent
8ff16c1990
commit
d9349175ad
52
api/next.txt
52
api/next.txt
@ -0,0 +1,52 @@
|
|||||||
|
pkg syscall (darwin-amd64), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (darwin-amd64), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (darwin-amd64-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (darwin-amd64-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (freebsd-386), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (freebsd-386), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (freebsd-386-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (freebsd-386-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (freebsd-amd64), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (freebsd-amd64), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (freebsd-amd64-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (freebsd-amd64-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (freebsd-arm), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (freebsd-arm), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (freebsd-arm-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (freebsd-arm-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (linux-386), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (linux-386), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (linux-386-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (linux-386-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (linux-amd64), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (linux-amd64), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (linux-amd64-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (linux-amd64-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (linux-arm), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (linux-arm), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (linux-arm-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (linux-arm-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (netbsd-386), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (netbsd-386), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (netbsd-386-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (netbsd-386-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (netbsd-amd64), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (netbsd-amd64), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (netbsd-amd64-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (netbsd-amd64-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (netbsd-arm), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (netbsd-arm), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (netbsd-arm-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (netbsd-arm-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (netbsd-arm64), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (netbsd-arm64), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (netbsd-arm64-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (netbsd-arm64-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (openbsd-386), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (openbsd-386), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (openbsd-386-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (openbsd-386-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (openbsd-amd64), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (openbsd-amd64), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
||||||
|
pkg syscall (openbsd-amd64-cgo), func SendtoInet4(int, []uint8, int, SockaddrInet4) error
|
||||||
|
pkg syscall (openbsd-amd64-cgo), func SendtoInet6(int, []uint8, int, SockaddrInet6) error
|
@ -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.
|
// WriteTo wraps the sendto network call.
|
||||||
func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
|
func (fd *FD) WriteTo(p []byte, sa syscall.Sockaddr) (int, error) {
|
||||||
if err := fd.writeLock(); err != nil {
|
if err := fd.writeLock(); err != nil {
|
||||||
|
@ -791,6 +791,16 @@ func (fd *FD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
|
|||||||
return ntotal, nil
|
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
|
// Call ConnectEx. This doesn't need any locking, since it is only
|
||||||
// called when the descriptor is first created. This is here rather
|
// called when the descriptor is first created. This is here rather
|
||||||
// than in the net package so that it can use fd.wop.
|
// than in the net package so that it can use fd.wop.
|
||||||
|
@ -82,6 +82,18 @@ func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
|
|||||||
return n, wrapSyscallError(writeToSyscallName, err)
|
return n, wrapSyscallError(writeToSyscallName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fd *netFD) writeToInet4(p []byte, sa syscall.SockaddrInet4) (n int, err error) {
|
||||||
|
n, err = fd.pfd.WriteToInet4(p, sa)
|
||||||
|
runtime.KeepAlive(fd)
|
||||||
|
return n, wrapSyscallError(writeToSyscallName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fd *netFD) writeToInet6(p []byte, sa syscall.SockaddrInet6) (n int, err error) {
|
||||||
|
n, err = fd.pfd.WriteToInet6(p, sa)
|
||||||
|
runtime.KeepAlive(fd)
|
||||||
|
return n, wrapSyscallError(writeToSyscallName, err)
|
||||||
|
}
|
||||||
|
|
||||||
func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
|
func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
|
||||||
n, oobn, err = fd.pfd.WriteMsg(p, oob, sa)
|
n, oobn, err = fd.pfd.WriteMsg(p, oob, sa)
|
||||||
runtime.KeepAlive(fd)
|
runtime.KeepAlive(fd)
|
||||||
|
@ -142,20 +142,20 @@ func internetSocket(ctx context.Context, net string, laddr, raddr sockaddr, soty
|
|||||||
return socket(ctx, net, family, sotype, proto, ipv6only, laddr, raddr, ctrlFn)
|
return socket(ctx, net, family, sotype, proto, ipv6only, laddr, raddr, ctrlFn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, error) {
|
func ipToSockaddrInet4(ip IP, port int) (syscall.SockaddrInet4, error) {
|
||||||
switch family {
|
|
||||||
case syscall.AF_INET:
|
|
||||||
if len(ip) == 0 {
|
if len(ip) == 0 {
|
||||||
ip = IPv4zero
|
ip = IPv4zero
|
||||||
}
|
}
|
||||||
ip4 := ip.To4()
|
ip4 := ip.To4()
|
||||||
if ip4 == nil {
|
if ip4 == nil {
|
||||||
return nil, &AddrError{Err: "non-IPv4 address", Addr: ip.String()}
|
return syscall.SockaddrInet4{}, &AddrError{Err: "non-IPv4 address", Addr: ip.String()}
|
||||||
}
|
}
|
||||||
sa := &syscall.SockaddrInet4{Port: port}
|
sa := syscall.SockaddrInet4{Port: port}
|
||||||
copy(sa.Addr[:], ip4)
|
copy(sa.Addr[:], ip4)
|
||||||
return sa, nil
|
return sa, nil
|
||||||
case syscall.AF_INET6:
|
}
|
||||||
|
|
||||||
|
func ipToSockaddrInet6(ip IP, port int, zone string) (syscall.SockaddrInet6, error) {
|
||||||
// In general, an IP wildcard address, which is either
|
// In general, an IP wildcard address, which is either
|
||||||
// "0.0.0.0" or "::", means the entire IP addressing
|
// "0.0.0.0" or "::", means the entire IP addressing
|
||||||
// space. For some historical reason, it is used to
|
// space. For some historical reason, it is used to
|
||||||
@ -173,11 +173,27 @@ func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, e
|
|||||||
// IPv6 address.
|
// IPv6 address.
|
||||||
ip6 := ip.To16()
|
ip6 := ip.To16()
|
||||||
if ip6 == nil {
|
if ip6 == nil {
|
||||||
return nil, &AddrError{Err: "non-IPv6 address", Addr: ip.String()}
|
return syscall.SockaddrInet6{}, &AddrError{Err: "non-IPv6 address", Addr: ip.String()}
|
||||||
}
|
}
|
||||||
sa := &syscall.SockaddrInet6{Port: port, ZoneId: uint32(zoneCache.index(zone))}
|
sa := syscall.SockaddrInet6{Port: port, ZoneId: uint32(zoneCache.index(zone))}
|
||||||
copy(sa.Addr[:], ip6)
|
copy(sa.Addr[:], ip6)
|
||||||
return sa, nil
|
return sa, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ipToSockaddr(family int, ip IP, port int, zone string) (syscall.Sockaddr, error) {
|
||||||
|
switch family {
|
||||||
|
case syscall.AF_INET:
|
||||||
|
sa, err := ipToSockaddrInet4(ip, port)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &sa, nil
|
||||||
|
case syscall.AF_INET6:
|
||||||
|
sa, err := ipToSockaddrInet6(ip, port, zone)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &sa, nil
|
||||||
|
}
|
||||||
return nil, &AddrError{Err: "invalid address family", Addr: ip.String()}
|
return nil, &AddrError{Err: "invalid address family", Addr: ip.String()}
|
||||||
}
|
}
|
||||||
|
@ -276,6 +276,14 @@ func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
|
|||||||
return 0, syscall.ENOSYS
|
return 0, syscall.ENOSYS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fd *netFD) writeToInet4(p []byte, sa syscall.SockaddrInet4) (n int, err error) {
|
||||||
|
return 0, syscall.ENOSYS
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fd *netFD) writeToInet6(p []byte, sa syscall.SockaddrInet6) (n int, err error) {
|
||||||
|
return 0, syscall.ENOSYS
|
||||||
|
}
|
||||||
|
|
||||||
func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
|
func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
|
||||||
return 0, 0, syscall.ENOSYS
|
return 0, 0, syscall.ENOSYS
|
||||||
}
|
}
|
||||||
|
@ -76,11 +76,23 @@ func (c *UDPConn) writeTo(b []byte, addr *UDPAddr) (int, error) {
|
|||||||
if addr == nil {
|
if addr == nil {
|
||||||
return 0, errMissingAddress
|
return 0, errMissingAddress
|
||||||
}
|
}
|
||||||
sa, err := addr.sockaddr(c.fd.family)
|
|
||||||
|
switch c.fd.family {
|
||||||
|
case syscall.AF_INET:
|
||||||
|
sa, err := ipToSockaddrInet4(addr.IP, addr.Port)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return c.fd.writeTo(b, sa)
|
return c.fd.writeToInet4(b, sa)
|
||||||
|
case syscall.AF_INET6:
|
||||||
|
sa, err := ipToSockaddrInet6(addr.IP, addr.Port, addr.Zone)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return c.fd.writeToInet6(b, sa)
|
||||||
|
default:
|
||||||
|
return 0, &AddrError{Err: "invalid address family", Addr: addr.IP.String()}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
|
func (c *UDPConn) writeMsg(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
|
||||||
|
@ -96,6 +96,14 @@ func Sendto(fd int, p []byte, flags int, to Sockaddr) error {
|
|||||||
return ENOSYS
|
return ENOSYS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SendtoInet4(fd int, p []byte, flags int, to SockaddrInet4) error {
|
||||||
|
return ENOSYS
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendtoInet6(fd int, p []byte, flags int, to SockaddrInet6) error {
|
||||||
|
return ENOSYS
|
||||||
|
}
|
||||||
|
|
||||||
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn, recvflags int, from Sockaddr, err error) {
|
func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn, recvflags int, from Sockaddr, err error) {
|
||||||
return 0, 0, 0, nil, ENOSYS
|
return 0, 0, 0, nil, ENOSYS
|
||||||
}
|
}
|
||||||
|
@ -292,6 +292,22 @@ func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SendtoInet4(fd int, p []byte, flags int, to SockaddrInet4) (err error) {
|
||||||
|
ptr, n, err := to.sockaddr()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return sendto(fd, p, flags, ptr, n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendtoInet6(fd int, p []byte, flags int, to SockaddrInet6) (err error) {
|
||||||
|
ptr, n, err := to.sockaddr()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return sendto(fd, p, flags, ptr, n)
|
||||||
|
}
|
||||||
|
|
||||||
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
|
func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
|
||||||
ptr, n, err := to.sockaddr()
|
ptr, n, err := to.sockaddr()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user