linux kernel中常见的宏

阅读数:158 评论数:0

跳转到新版页面

分类

Linux

正文

__CONCAT,连接两个参数,##用于粘贴两个参数,#用于替换参数

#define __CONCAT(a, b) a ## b

宏中使用do{...}while(0)的意义,用于定义复杂的宏,避免宏展开后分号造成编译不通过。

BUG_ON(condition)

条件为真,产生崩溃,相对应有WARN_ON

BUILD_BUG_ON

#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))

!!(e) 对 e 的结果进行两次求非。如果e为0,则结果为0;如果 e 不为 0,则结果为1。所以上述表达式的结果有两种:

  1. condition为真时,sizeof(char[-1]),产生错误,编译不通过

  2. condition为假时,sizeof(char[1]),编译通过

BUILD_BUG_ON_ZERO(e)

define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))

检查表达式e是否为0,为0编译通过且返回0;如果不为0,则编译不通过。

typecheck宏

/*
 * Check at compile time that something is of a particular type.
 * Always evaluates to 1 so you may use it easily in comparisons.
 */
#define typecheck(type,x) \
({ type __dummy; \
    typeof(x) __dummy2; \
    (void)(&__dummy == &__dummy2); \
    1; \
})
/*GCC的一个扩展特性,形如({ ... })这样的代码块会被视为一条语句,
* 其计算结果是{ ... }中最后一条语句的计算结果。
* 所以上述会返回1
*/
/*
 * Check at compile time that 'function' is a certain type, or is a pointer
 * to that type (needs to use typedef for the function type.)
 */
#define typecheck_fn(type,function) \
({ typeof(type) __tmp = function; \
    (void)__tmp; \
})

typecheck用于检查x是否为type类型,如果不是会抛出(warning: comparison of distinct pointer types lacks a cast),typecheck_fn用于检查函数function是否为type类型,不一致抛出(warning: initialization from incompatible pointer type)。

__is_constexpor

/*
 * This returns a constant expression while determining if an argument is
 * a constant expression, most importantly without evaluating the argument.
 * Glory to Martin Uecker <Martin.Uecker@med.uni-goettingen.de>
 */
#define __is_constexpr(x) \
    (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8)))

判断x是否为整数常量表达式,如果x是常量表达式,

sizeof(int) == sizeof(*((int *) (NULL))) // if `x` was an integer constant expression
sizeof(int) == sizeof(*((void *)(....))) // otherwise

因为sizeof(void)=1,所以如果x是整数常量表达式,则宏的结果为1,否则为0。

int  __builtin_types_compatible_p(type_a, type_b);

此函数为GNU扩展,用来判断两个类型是否相同,如果type_a与 type_b相同的话,就会返回1,否则的话,返回0。

roundup宏

#define roundup(x, y) ( \
{ \
    const typeof(y) __y = y; \
    (((x) + (__y - 1)) / __y) * __y; \
} \
)

返回一个能够除y并且大于x,最接近x的值,向上取整,可用于地址的内存对齐。

clamp宏

/**
 * clamp - return a value clamped to a given range with strict typechecking
 * @val: current value
 * @lo: lowest allowable value
 * @hi: highest allowable value
 *
 * This macro does strict typechecking of @lo/@hi to make sure they are of the
 * same type as @val. See the unnecessary pointer comparisons.
 */
#define clamp(val, lo, hi) min((typeof(val))max(val, lo), hi)

判断val是否在lo和hi的范围内,如果小于lo,返回lo,如果大于hi则返回hi,如果在lo和hi之间就返回val。

likely和unlikely宏

把分支预测的信息提供给编译器。

#define likely(x) __builtin_exp ect(!!(x), 1)
#define unlikely(x) __builtin_exp ect(!!(x), 0)

GCC的内建方法会判断 EXP == C 是否成立,成立则将if分支中的执行语句紧跟放在汇编跳转指令之后,否则将else分支中的执行语句紧跟汇编跳转指令之后。

这样cache在预取数据时就可以将分支后的执行语句放在cache中,提高cache的命中率。

ACCESS_ONCE

#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))

volatile表示不进行优化,访问目标地址一次,先取得x的地址,然后把这个地址转换成一个指向这个地址的指针,然后再取得这个指针所指向的内容,达到了访问一次的目的。

ACCESS_OK

检查指针是不是属于用户空间。

barrier()

/* Optimization barrier */
/* The "volatile" is due to gcc bugs */
#define barrier() __asm__ __volatile__("": : :"memory")

执行该语句后cpu中的寄存器和cache中已缓存的数据将作废,重新读取内存中的数据,这就阻止了cpu将寄存器和cache中的数据用于去优化指令。




相关推荐

一、概述 在Linux内核开发中,BUG_ON 宏是一个非常有用的调试工具。它用于在内核代码中检测异常情况,当检测到某个条件为真时,它会导致内核崩溃(crash),这通常意味着出现了严重的错误,需要开

// include/linux/compiler-gcc.h /** * asm指示后面的语句是汇编语句。 * volatile表示禁止对

/** * __builtin_expect(expr,c)编译器函数,用于告诉编译expr的值很可能是C */ #define