2 内核代码有效的定义
第一个部分介绍了汇编代码不使用的定义。下面开始介绍一下对内核代码有效的定义。
/*
* Allow us to mark functions as 'deprecated' and have gcc emit a nice
* warning for each use, in hopes of speeding the functions removal.
* Usage is:
* int __deprecated foo(void)
*/
#ifndef __deprecated
# define __deprecated /* unimplemented */
#endif
函数标记为deprecated,gcc在编译时会产生警告,提示尽快把这个函数移除。实际上deperated已经在compiler-gcc.h中定义了,如果有包含它,在这里将不会再定义。
#define __deprecated __attribute__((deprecated))
__deprecated通过gcc的__attribute__((deprecated))告诉gcc被标记对象的属性。
#ifdef MODULE
#define __deprecated_for_modules __deprecated
#else
#define __deprecated_for_modules
#endif
这里定义了MODULE的deprecated属性。
#ifndef __must_check
#define __must_check
#endif
__must_check宏的作用是告诉编译器当调用者调用这个函数时不使用返回结果产生一个告警。这个宏在compiler-gccx.h中定义了。使用了属性warn_unused_result。
#ifndef CONFIG_ENABLE_MUST_CHECK
#undef __must_check
#define __must_check
#endif
#ifndef CONFIG_ENABLE_WARN_DEPRECATED
#undef __deprecated
#undef __deprecated_for_modules
#define __deprecated
#define __deprecated_for_modules
#endif
这里定义了内核配置的选项,控制__must_check和__deprecated的开关。
/*
* Allow us to avoid 'defined but not used' warnings on functions and data,
* as well as force them to be emitted to the assembly file.
*
* As of gcc 3.4, static functions that are not marked with attribute((used))
* may be elided from the assembly file. As of gcc 3.4, static data not so
* marked will not be elided, but this may change in a future gcc version.
*
* NOTE: Because distributions shipped with a backported unit-at-a-time
* compiler in gcc 3.3, we must define __used to be __attribute__((used))
* for gcc >=3.3 instead of 3.4.
*
* In prior versions of gcc, such functions and data would be emitted, but
* would be warned about except with attribute((unused)).
*
* Mark functions that are referenced only in inline assembly as __used so
* the code is emitted even though it appears to be unreferenced.
*/
#ifndef __used
# define __used /* unimplemented */
#endif
#ifndef __maybe_unused
# define __maybe_unused /* unimplemented */
#endif
这个部分主要介绍了一下 函数和变量“定义却未使用”的情况下,编译器是否将其编译到目标汇编中。gcc采用used属性来告诉编译器,这个函数或变量是有用的,需要编译进汇编,避免被忽略。由于历史的原因,不同版本gcc对未引用的函数和变量是否会被忽略的处理不一样。
#ifndef noinline
#define noinline
#endif
/*
* Rather then using noinline to prevent stack consumption, use
* noinline_for_stack instead. For documentaiton reasons.
*/
#define noinline_for_stack noinline
#ifndef __always_inline
#define __always_inline inline
#endif
inline属性,关系到编译器是否会对比较小的函数进行内联优化。如果你不想编译器这么做,可以采用noinline属性告诉编译器,不需要内联。
3 通用的定义
前面两个部分介绍了汇编无效的定义和仅内核有效的定义,最后这部分定义了通用的定义,对汇编,内核代码和应用代码都有用。
/*
* From the GCC manual:
*
* Many functions do not examine any values except their arguments,
* and have no effects except the return value. Basically this is
* just slightly more strict class than the `pure' attribute above,
* since function is not allowed to read global memory.
*
* Note that a function that has pointer arguments and examines the
* data pointed to must _not_ be declared `const'. Likewise, a
* function that calls a non-`const' function usually must not be
* `const'. It does not make sense for a `const' function to return
* `void'.
*/
#ifndef __attribute_const__
# define __attribute_const__ /* unimplemented */
#endif
/*
* Tell gcc if a function is cold. The compiler will assume any path
* directly leading to the call is unlikely.
*/
#ifndef __cold
#define __cold
#endif
/* Simple shorthand for a section definition */
#ifndef __section
# define __section(S) __attribute__ ((__section__(#S)))
#endif
/*
* Prevent the compiler from merging or refetching accesses. The compiler
* is also forbidden from reordering successive instances of ACCESS_ONCE(),
* but only when the compiler is aware of some particular ordering. One way
* to make the compiler aware of ordering is to put the two invocations of
* ACCESS_ONCE() in different C statements.
*
* This macro does absolutely -nothing- to prevent the CPU from reordering,
* merging, or refetching absolutely anything at any time. Its main intended
* use is to mediate communication between process-level code and irq/NMI
* handlers, all running on the same CPU.
*/
#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
__attribute_const__在compiler-gcc.h里面定义为属性__const__,该属性的作用是告诉编译器,这个函数是无状态,它的输出完全依赖于它的输入。对于参数是指针,如果使用了指针指向的内容,也不能定义为__const__属性。
__cold属性只有gcc4.3以上的版本支持,作用是告诉编译器,这个函数可能不怎么用到,编译器会将这一类的函数放在速度低些的某个子section里面,而把非 __cold函数放在速度比较优的section里。
__section没什么好说的就是section属性的一个简易宏。
ACCESS_ONCE就是对这个变量取一次值,他采用了volatile,就使得所有访问该变量时都会从变量的地址中重新获取,而不会用缓存的值。但对于底层CPU来说,这个宏不起任何作用。主要是为了协调进程级别的代码和IRQ中断代码间的变量值的一致性。
到目前为止,对compiler.h文件的分析到这里就结束了,后面继续分析compiler-gcc.h的源码。
转载时请注明出处和作者联系方式
作者联系方式:张天才 mythfish@gmail.com