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

     


  • 相关阅读:
    初探动态规划(DP)
    高精度压位
    Poi写文件时报java.io.IOException: Read error
    mysql合并和时间函数
    线程池子线程先执行再执行主线程
    linux常用命令
    使用线程池应该注意的问题
    分页查询千万级数据慢
    待簳的题......
    记录脑残失误,让达摩克利斯之剑永远高悬
  • 原文地址:https://www.cnblogs.com/yuzaipiaofei/p/4124689.html
Copyright © 2020-2023  润新知