select-poll-epoll

select

sys_select()定义在 fs/select.c#595, 最终调用do_select().
do_select()循环遍历指定的fd,调用file->f_op->poll()方法获取这个fd的状态,然后加到返回结果里.如果没有fd要返回,就调用poll_schedule_timeout()切换到别的进程执行.
最终如果有fd加到了返回结果里,或者timeout了,或者有signal_pending,那就跳出循环,返回到user space.

poll

sys_poll()定义在 fs/select.c#914, 最终调用do_poll().
do_poll()一样遍历pollfd,调用do_pollfd(),进而调用file->f_op->poll()方法获取这个fd的状态.如果没有fd要返回,一样调用poll_schedule_timeout()切换到别的进程执行.
关于sys_poll()里restart_block部分,参看 http://man7.org/linux/man-pages/man2/restart_syscall.2.html
所以大的方面来说,select和poll没有本质的区别.

epoll

sys_epoll_create(int size)定义在 fs/eventpoll.c#1334, 它其实调用的是 sys_epoll_create1(0). size参数已经被忽略了.
sys_epoll_create1(int flags)定义在 fs/eventpoll.c#1306. 它就是简单的alloc了一个struct eventpoll,取得一个fd.
eventpoll是个RB tree.需要monitor的fd都插入到这个RB tree里.当fd ready时,kernel会把fd加到eventpoll的rdllist里.

epoll_ctl()就是简单的RB tree操作 insert, remove, mod.

epoll_wait()调用ep_poll(), ep_poll()检查eventpoll->rdllist是否有fd在里边,如果有,返回这些fd. 没有的话像select/poll一样切换到别的进程执行.