linux/compile.h头文件说明
的操作步骤,可以参看内核源码所带的文档.那上面说了这么多,与notrace这个属性有什么关系呢?在进行函数调用流程的显示过程中,是使用了两个 特殊的函数的,当函数被调用与函数被执行完返回之前,都会分别调用这两个特别的函数.如果不把这两个函数的函数指定为不被跟踪的属性,那么整个跟踪的过程 就会陷入一个无限循环当中.
#define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) 这两句是一对对应关系.__builtin_expect(expr, c)这个函数是新版gcc支持的,它是用来作代码优化的,用来告诉编译器,expr的期,非常有可能是c,这样在gcc生成对应的汇编代码的时候,会把相 应的可能执行的代码都放在一起,这样能少执行代码的跳转.为什么这样能提高CPU的执行效率呢?CPU在执行的时候,都是有预先取指令的机制的,把将 要执行的指令取出一部分出来准备执行.CPU不知道程序的逻辑,都是从可程序程序里挨着取的,如果这个时候,能不做跳转,则CPU预先取出的指令都可 以接着使用,反之,则预先取出来的指令都是没有用的.还有个问题是需要注意的,在__builtin_expect的定义中,以前的版本是没有!!这个符 号的,这个符号的作用其实就是负负得正,为什么要这样做呢?就是为了保证非零的x的值,后来都为1,如果为零的0值,后来都为0,仅此而已. #ifndef barrier # define barrier() __memory_barrier() #endif 这里表示如果没有定义barrier函数,则定义barrier()函数为__memory_barrier().但在内核代码里,是会包含 compiler-gcc.h这个文件的,在这个文件里,定义barrier()为__asm__ __volatile__("": : :"memory").barrier翻译成中文就是屏障的意思,在这里,为什么要一个屏障呢?这是CPU在执行的过程中,为了优化指令,可能会对部 分指令以它自己认为最优的方式进行执行,这个执行的顺序并不一定是按照程序在源码内写的顺序.编译器也有可能在生成二进制指令的时候,也进行一些优化.这 样就有可能在多CPU,多线程或是互斥锁的执行中遇到问题.那么这个内存屏障可以看作是一条线,内存屏障用在这里,就是为了保证屏障以上的操作,不会影响 到屏障以下的操作.然后再看看这个屏障怎么实现的.__asm__表示后面的东西都是汇编指令,当然,这是一种在C语言中嵌入汇编的方法,语法有其特殊 性,我在这里只讲跟这条指令有关的.__volatile__表示不对此处的汇编指令做优化,这样就会保证这里代码的正确性.""表示这里是个空指令,那 么既然是空指令,则所对应的指令所需要的输入与输出都没有.在gcc中规定,如果以这种方式嵌入汇编,如果输出没有,则需要两个冒号来代替输出操作数的位 置,需要加两个::,这时的指令就为"" : :.然后再加上为分隔输入而加入的冒号,再加上空的输入,即为"" : : :.后面的memory是gcc中的一个特殊的语法,加上它,gcc编译器则会产生一个动作,这个动作使gcc不保留在寄存器内内存的值,并且对相应的内 存不会做存储与加载的优化处理,这个动作不产生额外的代码,这个行为是由gcc编译器来保证完成的.如果对这部分有更大的兴趣,可以考察gcc的帮助文档 与内核中一篇名为memory-barriers.txt的文章. #ifndef RELOC_HIDE # define RELOC_HIDE(ptr, off) ({ unsigned long __ptr; __ptr = (unsigned long) (ptr); (typeof(ptr)) (__ptr (off)); }) #endif 这个没有什么太多值得讲的,也能看明白,虽然不知道具体用在哪里,留做以后遇到了再说吧. 接下来好多定义都没有实现,可以看一看注释就知道了,这里就不多说了.唉,不过再插一句,__deprecated属性的实现是为deprecated. #define noinline_for_stack noinline #ifndef __always_inline #define |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |