• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
yuzaipiaofei
博客园    首页    新随笔    联系   管理    订阅  订阅

几个常用的宏:likely和unlikely __raw_writel


在源码中,宏likely和unlikely 是这么定义的(位于include/linux/compiler.h):

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

要理解宏likely和unlikely ,很明显必须理解__builtin_expect。__builtin_expect是GCC(version>=2.9)引进的宏,其作用就是帮助编译器判断条件跳转的预期值,避免跳转造成时间浪费。拿下面的代码来说:

if (likely(acat == 1))     //表示大多数情况下if里面是真,程序大多数直接执行if里面的程序

而

if (unlikely (thread_memory_magazine1_is_empty (tmem, ix)))//表示大多数情况if里面为假,程序大多数直接执行else里面的程序

两段代码编译生成的汇编语句所使用到的跳转指令不一样,仔细分析下会发现__builtin_expect实际上是为了满足在大多数情况不执行跳转指令,所以__builtin_expect仅仅是告诉编译器优化,并没有改变其对真值的判断。

有关文章:http://kernelnewbies.org/FAQ/LikelyUnlikely

              http://hi.baidu.com/lammy/blog/item/bc5e3d4e869073c3d1c86a89.html

              http://www.cublog.cn/u/31100/showart_240658.html

__raw_writel到底干了些什么?

在linux/arch/arm/mach-at91/gpio.c 中 at91_set_gpio_output函数看到这个宏

int __init_or_module at91_set_gpio_output(unsigned pin, int value)

{

void __iomem *pio = pin_to_controller(pin);

unsigned mask = pin_to_mask(pin);

 

if (!pio)

return -EINVAL;

 

__raw_writel(mask, pio + PIO_IDR);

__raw_writel(mask, pio + PIO_PUDR);

__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));

__raw_writel(mask, pio + PIO_OER);

__raw_writel(mask, pio + PIO_PER);

return 0;

}

定义是:

#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
# define __chk_io_ptr(x) (void)0

这样看就是赋值,
__chk_io_ptr()是编译器为了更细致地检查参数的属性,用于调试,正常编译时没有作用。
volatile为了防止Compiler优化,说明它是一个随时被改变的量,每次使用它的时候,不应该被假设,而要从相应的寄存器中读取。

 


posted @ 2011-07-07 17:22  yuzaipiaofei  阅读(150)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3