首页 > 代码库 > likely和unlikey函数源码分析

likely和unlikey函数源码分析


likely和unlikey函数源码分析


            看代码的时候常常遇到likely和unlikely这两个函数,大概知道是用来检测返回值的,但是也不知道是什么。今天实在不爽了,就去看源码了。


在内核代码树的 include/linux/compiler.h里


void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);

#define likely_notrace(x)	__builtin_expect(!!(x), 1)
#define unlikely_notrace(x)	__builtin_expect(!!(x), 0)

#define __branch_check__(x, expect) ({								int ______r;								static struct ftrace_branch_data						__attribute__((__aligned__(4)))						__attribute__((section("_ftrace_annotated_branch"))) 				______f = {								.func = __func__,							.file = __FILE__,							.line = __LINE__,						};									______r = likely_notrace(x);						ftrace_likely_update(&______f, ______r, expect); 			______r;							})

/*
 * Using __builtin_constant_p(x) to ignore cases where the return
 * value is always the same.  This idea is taken from a similar patch
 * written by Daniel Walker.
 */
# ifndef likely
#  define likely(x)	(__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 1))
# endif
# ifndef unlikely
#  define unlikely(x)	(__builtin_constant_p(x) ? !!(x) : __branch_check__(x, 0))
# endif


我实在找不到__builtin_constant_p这个宏的定义了,应该就是检测x是否为内部常熟,如果是,likely和unlikely做出的处理都是!!(x),对原两次取逻辑非。


这样就把数据x,压缩到,0和1两个值了!

如果不是内置的常数,这里就要执行__branch_check__,而__branch_check__看起来很麻烦,我们只需要关注

			______r = likely_notrace(x);	
这行代码就OK了,其他代码不会影响_____r的值,而____r则是作为__branch_check__的返回值。

于是,我们看likely_notrace.


#define likely_notrace(x)	__builtin_expect(!!(x), 1)
两次取反和1比较,如果是1返回1,否则是0.

unlikely同理,只是期望的返回值是0罢了



如果以后有发现再update...