linux内核函数总结(likely & atomic & container_of & list_for_each_entry)

1、likely & unlikely

if (likely(value))等价于if (value)

if (unlikely(value))等价于if (value)

也就是说likely()和unlikely()从阅读和理解的角度是一样的。

# define likely(x)    __builtin_expect(!!(x), 1)
# define unlikely(x)    __builtin_expect(!!(x), 0)

使用likely(),执行if后面的语句的机会更大,使用unlikely(),执行else后面的语句机会更大一些;

编译器在编译过程中,会将可能性更大的代码紧跟着后面的代码,从而减少指令跳转带来的性能上的下降;

likely和unlikely的功能就是添加cache的命中率,提高系统执行速度。

2、atomic原子操作:

#define atomic_read(v)			READ_ONCE((v)->counter)
#define atomic_set(v, i)		WRITE_ONCE(((v)->counter), (i))

int atomic_read(const atomic_t *v)   获取atomic_t类型变量的值

void atomic_set(atomic_t *v, int i)  设置atomic_t类型变量的值

void atomic_add(int i, atomic_t *v)  增加i

void atomic_sub(int i, atomic_t *v)  减少i

3、container_of:

  container_of()的作用就是通过已知结构体type的成员member的地址ptr,求解结构体type的起始地址。

#define container_of(ptr, type, member) ({			\
	const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
	(type *)( (char *)__mptr - offsetof(type,member) );})
||
||
#define container_of(ptr, type, member) 
    ({
        const typeof( ((type *)0)->member ) *__mptr = (ptr);//第一步
        (type *)( (char *)__mptr - offsetof(type,member) );//第二步
    }) 

(1)类型检查: 判断ptr 与 member 的类型是否相同,简单意思:__mptr = ptr

(2)type的起始地址 = ptr - size  

  即:结构体的起始地址 = (type *)((char *)ptr - size),size = offsetof(type,member)

  offsetof计算TYPE结构体MEMBER成员的偏移量,也就是对应的size:

#define offsetof(TYPE, MEMBER)	((size_t)&((TYPE *)0)->MEMBER)

  关于((size_t)&((TYPE *)0)->MEMBER) 的含义,可以用下面的代码清晰简单的理解:

#include<stdio.h>
struct test
{
	char i ;
	int j;
	char k;
};
int main()
{
	struct test temp;
	printf("&temp = %p\n",&temp);   
	printf("&temp.k = %p\n",&temp.k);
	printf("&((struct test *)0)->k = %d\n",((int)&((struct test *)0)->k));
}

=====> result:
&temp = 0x7fff097e8f90
&temp.k = 0x7fff097e8f98
&((struct test *)0)->k = 8   //获取到k成员的偏移量

4、list_for_each_entry:

  它实际上是一个 for 循环,利用传入的 ptr作为循环变量,从表头 head 开始,逐项向后( next方向)移动 ptr ,

直至又回到 head,就是遍历 ptr 的链表成员。

#define list_for_each_entry(ptr, head, member) \
	for (ptr = list_entry((head)->next, typeof(*ptr), member); \
		&ptr->member != (head); \
		ptr = list_entry(ptr->member.next, typeof(*ptr), member))
||
||
#define list_for_each_entry(ptr, head, member) \
	for (
            ptr = list_entry((head)->next, typeof(*ptr), member); //第一步
            &ptr->member != (head); //第二步
            ptr = list_entry(ptr->member.next, typeof(*ptr), member) //第三步
        )

(1)for循环初始化 :ptr = list_entry((head)->next, typeof(*ptr), member);

#define list_entry(ptr, type, member)   container_of(ptr, type, member)

(2)for循环执行条件:&ptr->member != (head)

(3)ptr = list_entry(ptr->member.next, typeof(*ptr), member)

可以下图表示,pos = ptr:

作者:frank_zyp
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文无所谓版权,欢迎转载。

猜你喜欢

转载自blog.csdn.net/frank_zyp/article/details/86064775
今日推荐