-
-
Save victorstewart/98814b65ed702c33480487c05b40eb56 to your computer and use it in GitHub Desktop.
fastpoll accept test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef IORING_OP_SHUTDOWN | |
#define IORING_OP_SHUTDOWN IORING_OP_TEE + 1 | |
#endif | |
#include <errno.h> | |
#include <linux/io_uring.h> | |
#include <liburing/src/include/liburing.h> | |
#include <sys/un.h> | |
#include <sys/socket.h> | |
#include <unistd.h> // unlink | |
#include <string> | |
// clang++ -fuse-ld=lld --std=gnu++2a -I/folder/with/liburing /path/to/liburing.a -o accept.test accept.test.cpp -g | |
class UnixSocket { | |
public: | |
int fd; | |
struct sockaddr_un address = {}; | |
socklen_t addressLen; | |
UnixSocket(const char *socketpath) | |
{ | |
fd = socket(AF_UNIX, SOCK_STREAM, 0); | |
addressLen = sizeof(struct sockaddr_un); | |
address.sun_family = AF_UNIX; | |
memcpy(address.sun_path, socketpath, strlen(socketpath)); | |
unlink(address.sun_path); | |
bind(fd, (struct sockaddr *)&address, addressLen); | |
listen(fd, SOMAXCONN); | |
} | |
~UnixSocket() | |
{ | |
close(fd); | |
} | |
}; | |
class AcceptServer { | |
public: | |
struct io_uring ring; | |
int *socketfds = new int[10]; | |
void setup(int fd, bool useSQPOLL) | |
{ | |
int cpu_pin = sched_getcpu(); | |
cpu_set_t affinity; | |
CPU_SET(cpu_pin, &affinity); | |
sched_setaffinity(0, sizeof(affinity), &affinity); | |
struct io_uring_params params = {}; | |
if (useSQPOLL) | |
{ | |
params.flags = IORING_SETUP_SQPOLL | IORING_SETUP_SQ_AFF; | |
params.sq_thread_idle = 2000; // ms | |
params.sq_thread_cpu = cpu_pin; | |
} | |
io_uring_queue_init_params(1024, &ring, ¶ms); | |
memset(socketfds, 0xff, sizeof(int) * 10); // make sparse with -1 | |
socketfds[fd] = fd; | |
io_uring_register_files(&ring, socketfds, 10); | |
} | |
void queueAccept(UnixSocket *socket, bool useFixedFileFlag) | |
{ | |
struct io_uring_sqe *sqe = io_uring_get_sqe(&ring); | |
io_uring_prep_accept(sqe, socket->fd, (struct sockaddr *)&(socket->address), &(socket->addressLen), 0); | |
if (useFixedFileFlag) io_uring_sqe_set_flags(sqe, IOSQE_FIXED_FILE); | |
} | |
int run(bool useSQPOLL, bool useFixedFileFlag) | |
{ | |
UnixSocket *socket = new UnixSocket("hot.socket"); | |
setup(socket->fd, useSQPOLL); | |
int acceptResult = 0; | |
queueAccept(socket, useFixedFileFlag); | |
struct io_uring_cqe *cqe = NULL; | |
struct __kernel_timespec timeout = {.tv_sec = 2, .tv_nsec = 0}; | |
// if accept works... this should timeout | |
if (io_uring_wait_cqe_timeout(&ring, &cqe, &timeout) != -ETIME) | |
{ | |
// failed | |
acceptResult = cqe->res; | |
} | |
io_uring_queue_exit(&ring); | |
delete socket; | |
return acceptResult; | |
} | |
}; | |
int main (int argc, char *argv[]) | |
{ | |
AcceptServer *server = new AcceptServer(); | |
auto printResult = [&] (const char *testname, int result) -> void { | |
if (result == 0) printf("%s -> SUCCESS: timeout as expected\n", testname); | |
else printf("%s -> FAILURE: failed with error = %d\n", testname, result); | |
}; | |
printResult("with SQPOLL with FIXED FLAG", server->run(true, true)); | |
// only relevant >=5.11 | |
//printResult("with SQPOLL without FIXED FLAG", server->run(true, false)); | |
printResult("without SQPOLL with FIXED FLAG", server->run(false, true)); | |
printResult("without SQPOLL without FIXED FLAG", server->run(false, false)); | |
delete server; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment