Estoy migrando mi proyecto a io_uring para un mejor rendimiento. Sin embargo, una parte del sistema depende de que epoll sea un sistema de eventos y no se pueda mover a io_uring (por ejemplo, los controladores de la base de datos escriben en el socket internamente y recibo notificaciones de eventos de lectura/escritura, sin ver nunca lo que está escrito en los sockets sin formato). Obligándome a usar epoll y io_uring juntos. Crear dos hilos, uno para epoll y otro para io_uring no es una opción por varias razones.
Mi plan era sondear io_uring después de epoll en mi ciclo de eventos, como el siguiente
while(keep_running) { epoll_wait(); io_uring_peek_batch_cqe(); ... // handle events } Esto resulta no viable. Es probable que no haya actividad continua en la base de datos, lo que provoca que epoll_wait se bloquee hasta que se agote el tiempo de espera, por lo que todas las operaciones en io_uring esperan el mismo tiempo de espera. Ni invertir el orden y llamar a io_uring_wait_cqe mejor. Es posible que haya tráfico de base de datos pero nada enviado a io_uring. Causando que epoll espere el tiempo de espera de io_uring.
Hasta ahora he considerado reducir el tiempo de espera. Pero no es una solución elegante. Aumenta el uso de la CPU y agrega latencia innecesaria. ¿Hay alguna manera de esperar epoll y io_uring al mismo tiempo? es decir, alguna función que se desbloquea tan pronto como epoll o io_uring tienen algo que procesar.
io_uring puede monitorear los descriptores de archivos para determinar si están listos usando IORING_OP_POLL_ADD. Epoll fd se vuelve listo para leer una vez que hay algunos eventos pendientes. Una solución es usar io_uring como la principal función de notificación de eventos. Epoll fd debe ser monitoreado por io_uring.
Se podría hacer al revés: usar epoll como la principal función de notificación de eventos. Configure io_uring para publicar notificaciones de preparación usando eventfd y agréguelo a epoll: https://unixism.net/loti/tutorial/register_eventfd.html