本文基于2.6.39内核
第一部分已经大致的介绍了linux在实现EPOLL模型所用到的主要数据结构,接下来这篇就是主要分析怎样通过这些数据结构来实现EPOLL的功能。
一。模块的加载
linux把EPOLL当做一个模块,模块入口函数的代码如下:
/************epoll模块入口函数***********/ static int __init eventpoll_init(void) { struct sysinfo si; si_meminfo(&si); /* * Allows top 4% of lomem to be allocated for epoll watches (per user). */ max_user_watches = (((si.totalram - si.totalhigh) / 25) << PAGE_SHIFT) / EP_ITEM_COST; BUG_ON(max_user_watches < 0); /* * Initialize the structure used to perform epoll file descriptor * inclusion loops checks. */ ep_nested_calls_init(&poll_loop_ncalls); /* Initialize the structure used to perform safe poll wait head wake ups */ ep_nested_calls_init(&poll_safewake_ncalls); /* Initialize the structure used to perform file's f_op->poll() calls */ ep_nested_calls_init(&poll_readywalk_ncalls); /* Allocates slab cache used to allocate "struct epitem" items */ epi_cache = kmem_cache_create("eventpoll_epi", sizeof(struct epitem), 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); /* Allocates slab cache used to allocate "struct eppoll_entry" */ pwq_cache = kmem_cache_create("eventpoll_pwq", sizeof(struct eppoll_entry), 0, SLAB_PANIC, NULL); return 0; } fs_initcall(eventpoll_init); /*fs_initcall 函数即是module_init函数*/
这个函数主要是进行一些初始化配置,同时创建了2个内核cache用于存放epitem和epoll_entry。
二 epoll_create函数的实现
epoll_create 创建一个epoll实例,即一个epoll的文件(epfd),同时创建并初始化一个struct eventpoll,其中efpd所对应的file的private_data指针即指向了eventpoll变量,因此,知道epfd就可以拿到file,即拿到了eventpoll变量。
下面我们来看具体实现: