From 56ba714e1039ebc128e533c408b3b936dcd09b5d Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Tue, 1 Jun 2021 22:11:40 -0700 Subject: [PATCH] smush together two return values from C avoids a per-packet alloc i will atone for my sins later if only C let you return multiple values. or Go let you pass in a pointer w/o it being on the heap. --- net/uring/io_uring.c | 17 ++++++++++------- net/uring/io_uring_linux.go | 9 +++++---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/net/uring/io_uring.c b/net/uring/io_uring.c index e3eb73e06..5f8b4a099 100644 --- a/net/uring/io_uring.c +++ b/net/uring/io_uring.c @@ -20,7 +20,7 @@ typedef struct iovec go_iovec; typedef struct sockaddr_in go_sockaddr_in; // Wait for a completion to be available, fetch the data -static int receive_into(struct io_uring *ring, size_t *idxptr) { +static uint64_t receive_into(struct io_uring *ring) { struct io_uring_cqe *cqe; again:; @@ -38,15 +38,18 @@ again:; fprintf(stderr, "recvmsg failed: %d.\n", cqe->res); return cqe->res; } - *idxptr = (size_t)(io_uring_cqe_get_data(cqe)); - if (*idxptr < 0) { + size_t idxptr = (size_t)(io_uring_cqe_get_data(cqe)); + uint32_t idxptr32 = (uint32_t)(idxptr); + uint64_t idxptr64 = (uint64_t)(idxptr32); + uint64_t n = cqe->res; + uint32_t n32 = (uint32_t)n; + uint64_t n64 = (uint64_t)n; + io_uring_cqe_seen(ring, cqe); + if (idxptr < 0) { fprintf(stderr, "received nop\n"); - io_uring_cqe_seen(ring, cqe); return -1; } - int n = cqe->res; - io_uring_cqe_seen(ring, cqe); - return n; + return (n64 << 32) | idxptr64; } static uint32_t ip(struct sockaddr_in *sa) { diff --git a/net/uring/io_uring_linux.go b/net/uring/io_uring_linux.go index 7eeb2f5c6..44ff4be09 100644 --- a/net/uring/io_uring_linux.go +++ b/net/uring/io_uring_linux.go @@ -56,7 +56,7 @@ func NewUDPConn(conn *net.UDPConn) (*UDPConn, error) { } r := new(C.go_uring) - const queue_depth = 8 // TODO: What value to use here? + const queue_depth = 16 // TODO: What value to use here? C.io_uring_queue_init(queue_depth, r, 0) u := &UDPConn{ ptr: r, @@ -95,11 +95,12 @@ func (u *UDPConn) ReadFromNetaddr(buf []byte) (int, netaddr.IPPort, error) { if u.fd == 0 { return 0, netaddr.IPPort{}, errors.New("invalid uring.UDPConn") } - var idx C.size_t - n := C.receive_into(u.ptr, &idx) - if n < 0 { + nidx := C.receive_into(u.ptr) + if int64(nidx) == -1 { return 0, netaddr.IPPort{}, errors.New("something wrong") } + idx := uint32(nidx) + n := uint32(nidx >> 32) r := &u.reqs[int(idx)] ip := C.ip(&r.sa) var ip4 [4]byte