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...

likely和unlikey函数源码分析

时间: 2024-08-27 13:07:30

likely和unlikey函数源码分析的相关文章

math.h()函数源码

hypot()函数源码 /* hypot函数对于给定的直角三角形的两个直角边, 求其斜边的长度. */ //一般的常规算法: double my_hypot01(double x, double y) { double hypotenuse; x = fabs(x); y = fabs(y); if (x < y) { double temp = x; x = y; y = temp; } if (x == 0.) return 0.; else { hypotenuse = y/x; retu

ctype.h函数源码

iscsym()函数源码 int my_iscsym(int c) { return (isalnum(c) || ( c == '_' )); }//判断字符c是否为英文字母.数字和下划线 int main() { char ch = 'a'; if(my_iscsym(ch)) printf("%c is English, UnderLine Character or Number! /n",ch); else printf("%c is not a English, 

C语言字符串处理函数源码

strstr()函数源码 /* 得到s1中第一次包含s2字符串的位置指针. */ #include <stdlib.h> char * my_strstr(const char *s1,const char *s2) { if (*s1 == 0) { if (*s2) return (char *) NULL; return (char *) s1; } while (*s1) { size_t i; i = 0; while (1) { if (s2[i] == 0) { return (

巡风视图函数源码学习--view.py

记录一下巡风扫描器view.py这个脚本里的视图函数的学习,里面有一些print 代码是为了把数据打印出来小白我自己加的,勿怪勿怪.可能存在一些理解错误和不到位的地方,希望大佬多多指正.. 0x01:跳转到登陆页面 第二遍看这个脚本的源码时,想到一个问题,如果你在浏览器地址栏里输入http://127.0.0.1/login可以跳转到登陆页面,如果只输入127.0.0.1,这时候并没有运行Login这个视图函数,却也能直接跳转到登陆页面,这是为什么呢?原来,在Main视图函数上面有这样两行代码:

OpenCV 源码中分水岭算法 watershed 函数源码注解

为了研究分水岭算法,阅读了OpenCV 2.4.9 中watershed函数的源码实现部分,代码位于 opencv\sources\modules\imgproc\src\segmentation.cpp 文件中.先贴出加了注解的代码,以后补充对分水岭算法的解释. #include "precomp.hpp" /******************************************************* Watershed **********************

阻止函数源码在控制台输出

这是一个很贱的技能,我在谷歌控制台源码里看到的.相信大家都知道,在控制台里只输入函数名,不输入 () 然后按回车,就可以输出源码. 都不会陌生吧,这也有助于我们调试,是个很棒的技巧.不过系统内置的就会输出  function alert() { [native code] } 比如这个. 不过当我们输入 dir 的时候却看到: WTF,Command Line API ?难道也是系统的?以前我以为是,后来发现其实不是,而是一个js处理输出的,防止输出源码的方法. 让我们来找到他的源代码吧.在控制

printf函数源码实现

#include <stdio.h> #include <stdarg.h> //va_start(arg,format),初始化参数指针arg,将函数参数format右边第一个参数地址赋值给arg //format必须是一个参数的指针,所以,此种类型函数至少要有一个普通的参数,  //从而提供给va_start ,这样va_start才能找到可变参数在栈上的位置.  //va_arg(arg,char),获得arg指向参数的值,同时使arg指向下一个参数,char用来指名当前参数

查看R中的函数源码

最近在学习概率统计,对于R的统计函数,有时需要看看它计算用的是哪个公式,都有什么参数.除了直接help和?之外,是简单的办法莫过于: 1.直接输入函数名,如qnorm 2.methods()方法,但methods(qnorm)显示不是同类函数.其原理有待查明. 3.str(object),简洁的显示object的结构 4.mode(),class()等,可以简单查明对象的类型,如是不是一个函数.

java-round函数源码

看不懂,改天研究?如果记得的话 public static long round(double a) { long longBits = Double.doubleToRawLongBits(a); long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK) >> (DoubleConsts.SIGNIFICAND_WIDTH - 1); long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2