epoll
epoll means edge polling. It means when edge states are changed, the relevant events are triggered.
The name epoll is misleading. In reality there is no polling. The kernel directly receives external IO events and updates all waiting file descriptors.
epoll is used only for monitoring file descriptors for IO events. Kernel is involved directly whenever an IO state changes.
Futex is used for non IO use cases such as blocking queues.
Legacy Polling Mechanism
For all IO tasks, the kernel updates the file descriptor flags to signal if there is data ready to be acted upon.
This would mean, the user space applications must pass all the file descriptors that they need to check and kernel will have to update back if any flag has changed. This polling has complexity of 0(n) and the polling also involves system call which needs data to be copied between userspace and kernel space.
If the caller of the poll system call wants to wait for the events, the call is done with timeout as minus 1. In this case, the kernel will put the thread to sleep until there is a state change in any of the file descriptors.
Protection Layer
epoll avoids userspace from polling the file descriptors. Instead, we ask kernel to create an epoll instance and ask it to monitor whichever file descriptors we're interested in.
After this, epoll monitors the file descriptors independently. Whenever there is state change, the thread is scheduled again by the kernel. It was earlier paused exactly at the step where it called the epoll_wait system call, and now it will be scheduled again to check the events.
In most cases, the thread state is changed to TASK_INTERRUPTIBLE, this means the thread isn't scheduled anymore by the kernel.
When there is a state change, the thread state is changed back to TASK_RUNNING and the thread is scheduled again by the kernel.
