第十四章:分配内存

 

内核提供了下面的一般用途的内存分配函数:kmalloc()kzalloc()kcalloc()

vmalloc()。请参考API文档以获取有关它们的详细信息。

传递结构体大小的首选形式是这样的:

 

        p = kmalloc(sizeof(*p), ...);

 

另外一种传递方式中,sizeof的操作数是结构体的名字,这样会降低可读性,并且可能会引入bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的sizeof的结果不变。

 

强制转换一个void指针返回值是多余的。C语言本身保证了从void指针到其他任何指针类型的转换是没有问题的。

 

 

                第十五章:内联弊病

 

有一个常见的误解是内联函数是gcc提供的可以让代码运行更快的一个选项。虽然使用内联函数有时候是恰当的(比如作为一种替代宏的方式,请看第十二章),不过很多情况下不是这样。inline关键字的过度使用会使内核变大,从而使整个系统运行速度变慢。因为大内核会占用更多的指令高速缓存(译注:一级缓存通常是指令缓存和数据缓存分开的)而且会导致pagecache的可用内存减少。想象一下,一次pagecache未命中就会导致一次磁盘寻址,将耗时5毫秒。5毫秒的时间内CPU能执行很多很多指令。

 

一个基本的原则是如果一个函数有3行以上,就不要把它变成内联函数。这个原则的一个例外是,如果你知道某个参数是一个编译时常量,而且因为这个常量你确定编译器在编译时能优化掉你的函数的大部分代码,那仍然可以给它加上inline关键字。kmalloc()内联函数就是一个很好的例子。

 

人们经常主张给static的而且只用了一次的函数加上inline,不会有任何损失,因为这种情况下没有什么好权衡的。虽然从技术上说,这是正确的,不过gcc可以在没有提示的情况下自动使其内联,而且其他用户可能会要求移除inline,此种维护上的争论会抵消可以告诉gcc来做某些事情的提示带来的潜在价值。不管有没有inline,这种函数都会被内联。