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