几个常用的宏: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优化,说明它是一个随时被改变的量,每次使用它的时候,不应该被假设,而要从相应的寄存器中读取。

 


原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124688.html