Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1301202
  • 博文数量: 548
  • 博客积分: 7597
  • 博客等级: 少将
  • 技术积分: 4224
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-15 13:21
个人简介

嵌入式软件工程师&&太极拳

文章分类

全部博文(548)

文章存档

2014年(10)

2013年(76)

2012年(175)

2011年(287)

分类:

2011-12-29 11:37:56

原文地址:IS_ERR简单分析 作者:lapset

static inline long IS_ERR(const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
}

内核返回的指针一般是指向页面的边界(4K边界),即
ptr & 0xfff == 0
这样ptr的值不可能落在(0xfffff000,0xffffffff)之间,
而一般内核的出错代码也是一个小负数,在-1000到0之间,转变成unsigned long,
正好在(0xfffff000,0xffffffff)之间。因此可以用

(unsigned long)ptr > (unsigned long)-1000L
来判断内核函数的返回值是一个有效的指针,还是一个出错代码。
 

#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
# 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
这个地方简单说下likely(x)和unlikely(x)
这两个函数其实对应的,而这只是结果不同而已,作用都是提高代码优化度,因为它们能够有效的预测分支。
其中
__builtin_constant_p(x)的功能是判断x是变量还是const
如果是常量的话,则!!(x),这个功能不需要我多说吧。取bool值,如果是变量,则执行__branch_check__
#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;     \
  })
 

别人的分析是:__branch_check__宏,记录当前trace点,并利用ftrace_likely_update记录likely判断的正确性,并将结果保 存在ring buffer中,之后用户可以通过ftrace的debugfs接口读取分支预测的相关信息。从而优调整代码,优化性能。
重定义likely和unlikely宏里面用到了GCC的build-in函数__builtin_constant_p判断一个表达式在编译时是否为 常量。当是常量时,直接返回likely和unlikely表达式的值,没必要做预测的记录。当表达式为非常数时,使用宏 __branch_check__检查分支并记录likely判断的预测信息。
 
 
阅读(919) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~