首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件开发 >

epoll源码分析-sys_epoll_create()函数

2013-01-23 
epoll源码分析---sys_epoll_create()函数 eventpoll的优点就不用说了,网上的资料很多,eventpoll的使用也很

epoll源码分析---sys_epoll_create()函数
 eventpoll的优点就不用说了,网上的资料很多,eventpoll的使用也很广泛,特别是在Web服务器中。因为最近要用到epoll,所以好好地看了一下它的实现,把学到的一些东西做下整理,做个记录。一、sys_epoll_create()  其源码如下:

  • #define BUILD_BUG_ON(condition) ((void)BUILD_BUG_ON_ZERO(condition))宏BUILD_BUG_ON_ZERO的定义如下:
    /* * find_next_zero_bit返回的值的范围是0~(size-1),相当于是bit数组中的索引 * @addr: 位图的地址 * @size: 位图的bit位个数 * @offset: 可以理解为bit数组中的索引,也就是说从这个bit位开始查找 */unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,                 unsigned long offset){    /*     * 这里BITOP_WORD用来计算offset对应位图中的unsigned long元素在     * addr数组中的索引,所以p为offset所在的unsigned long元素的地址     */    const unsigned long *p = addr + BITOP_WORD(offset);    /*     * 相当于是offset - (offset % BITS_PER_LONG),也就是offset所在的unsigned long     * 之前所有unsigned long元素的bit位个数     */    unsigned long result = offset & ~(BITS_PER_LONG-1);    unsigned long tmp;    /*     * 如果偏移量大于等于位图的大小,则直接     * 返回size。     */    if (offset >= size)        return size;    /*     * 计算offset所在的unsigned long及其之后所有的unsigned long元素中     * 的bit位个数     */    size -= result;    /*     * 计算offset对应的unsigned long中占用的bit位所在的位置,这个也可以理解     * 为一个索引。假设计算前offset的值为67,计算后offset的值为3,也就是所在     * unsigned long中的第4个bit位。     */    offset %= BITS_PER_LONG;    if (offset) {        /*         * tmp的值为offset所在的unsigned long的值         */        tmp = *(p++);        /*         * BITS_PER_LONG - offset计算的offset所在的unsigned long元素中offset所在的         * bit位及其之后的bit位个数。tmp中offset所对应的bit位及其之后的bit位都保留,而将         * tmp中offset所对应的bit位之前的bit位都设置为1.         */        tmp |= ~0UL >> (BITS_PER_LONG - offset);        /*         * 如果size小于BITS_PER_LONG,说明offset在最后一个unsigned long元素。         */        if (size < BITS_PER_LONG)            goto found_first;        /*         * 如果tmp取反后为不为0,则说明tmp中有为0的bit位,因此从         * tmp中查找空闲的bit位。         */        if (~tmp)            goto found_middle;        /*         * 如果offset所对应的bit位所在的unsigned long中没有空闲的bit位,         * 开始从其之后得unsigned long元素中查找。计算剩余的bit位个数,         * 修改已经查找的bit位个数         */        size -= BITS_PER_LONG;        result += BITS_PER_LONG;    }    /*     * 如果size小于BITS_PER_LONG,则退出循环     */    while (size & ~(BITS_PER_LONG-1)) {        /*         * 将下一个查找的元素存储在tmp中,如果tmp取反后不为0,则说明tmp中有为0的bit位,因此         * 从tmp中查找空闲的bit位。         */        if (~(tmp = *(p++)))            goto found_middle;        /*         * 计算剩余的bit位个数,修改已经查找的bit位个数         */        result += BITS_PER_LONG;        size -= BITS_PER_LONG;    }    /*     * 如果全部查找后,仍没有找到空闲的bit位,则直接返回result。     * 此时result的值应该为位图的bit位的个数。     */    if (!size)        return result;    /*     * 如果size不为0,则在剩余的最后的bit位(剩余的个数小于BITS_PER_LONG)中查找。     */    tmp = *p;found_first:    /*     * 因为剩余的bit位个数有可能小于BITS_PER_LONG,因此需要将unsigned long中     * 不用的bit位置为1,以免干扰后续的查找     */    tmp |= ~0UL << size;    /*     * 如果所有bit位都为1,则说明没有空余的bit位,     * 则返回所有的bit位的个数。     */    if (tmp == ~0UL)    /* Are any bits zero? */        return result + size;    /* Nope. */found_middle:    /*     * ffz(tmp)返回的是tmp中第一个为0的bit位的索引     */    return result + ffz(tmp);}

  • 热点排行