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:
可以使用如下代码变量当前系统所有的进程信息:
static int __init traverse_init(void){
struct task_truct *pos;
struct list_head *current_head;
int count = 0;
printk("Traversal module is working!!!");
current_head = &(current->tasks);
list_for_each_entry(pos, current_head, tasks){
count ++;
}
printk("The number of process is: %d \n",count);
}
对应的效果:
作者:frank_zyp
您的支持是对博主最大的鼓励,感谢您的认真阅读。
本文无所谓版权,欢迎转载。