为什么包装功能?

时间:2017-11-10 15:43:06

标签: linux kernel c

为什么Linux内核有时会实现多个版本的函数,这些函数的名称非常相似,只能包装另一个函数?例如,here

static void clocksource_select(void)
{
    __clocksource_select(false);
}

static void clocksource_select_fallback(void)
{
    __clocksource_select(true);
}

1 个答案:

答案 0 :(得分:2)

您给出的示例不是一个很好的示例,因为它与Linux内核无关。这只是基本的软件工程。

当你有两个功能需要非常接近的功能时,你可以选择几个路径。

  1. 您可以执行此功能两次。我们不喜欢这样做,因为它会创建代码重复。这也意味着如果你需要在代码的公共区域更改某些内容,你需要记住在两个地方更改它。

  2. 您可以将公共代码拆分为自己的函数,并从每个函数中调用该函数。如果可能的话,这是的最佳解决方案。问题是它并非总是可行。这可能是不可能的,因为公共代码需要太多的上下文,或者因为它需要在整个函数中展开。这使我们有权:

  3. 创建内部"常见" function,带有一个参数,告诉你提供哪些功能。只需编写代码,并将-Dorg.slf4j.simpleLogger.defaultLogLevel=error -Dorg.slf4j.simpleLogger.log.assimp.Assimp=warn 放在两个函数需要执行不同操作的位置。这是内核在你的例子中所采用的路径。

  4. 话虽如此,还有另一个特定于Linux内核的案例,其中两个函数确实看起来几乎相同。在i386平台上,if系统调用不会执行两次,而是三次:

    • stat系统电话号码18
    • oldstat系统号码106
    • stat系统号码195

    原因在于Linux内核承诺在其用户空间内核接口上完全向后兼容。当某个函数由于某种原因必须被取代时,stat64不是一次,而是两次(如果算上stat则三次),旧的系统调用条目需要保持并保持运作。

    但是,如果你看一下实际的实现,你会发现它们之间几乎没有什么区别,它们最终都会调用相同的功能。