【问题标题】:what does "static int function(...) __acquires(..) __releases(...){" mean?“静态int函数(...)__acquires(..)__releases(...){”是什么意思?
【发布时间】:2014-01-09 11:21:44
【问题描述】:

我最近在 Linux 内核中得到了一段 sn-p 代码:

static int
fb_mmap(struct file *file, struct vm_area_struct * vma)
__acquires(&info->lock)
__releases(&info->lock)
{
...
}

让我感到困惑的是static int fb_mmap() 后面紧跟在"{" 之前的两个__function,

a).这两个__函数的作用是什么?

b).为什么在那个位置?

c).为什么他们有前缀"__"

d).还有其他类似的例子吗?

【问题讨论】:

  • 它们很可能是宏,因此请在头文件中搜索它们的定义。
  • @JoachimPileborg 我不记得在 C 语法中你可以把任何东西放在那个位置。
  • 宏很可能会扩展为 GCC 扩展 __attribute__,它确实可以放在那个位置。

标签: c linux linux-kernel linux-device-driver


【解决方案1】:

并非所有以括号结尾的东西都是函数(调用)。在这种情况下,它们是参数化的宏扩展。宏定义为

#define __acquires(x)  __attribute__((context(x,0,1)))
#define __releases(x)  __attribute__((context(x,1,0)))

在内核构建树的文件include/linux/compiler.h中。

这些宏扩展到属性定义的目的是用函数将获取(即锁定)和释放(即解锁)的锁定结构的信息来注释函数符号。尤其是这些目的是调试锁定机制(Linux 内核包含一些代码,允许它检测潜在的死锁情况并报告此情况)。

https://en.wikipedia.org/wiki/Sparse

__attribute__ 是特定于 GCC 编译器的关键字,它允许将属性分配给给定的符号 http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes

由于宏是在文本级别展开的,因此在编译器甚至还没有查看宏之前,实际编译器看到的特定 sn-p 的结果将是

static int
fb_mmap(struct file *file, struct vm_area_struct * vma)
__attribute__((context(&info->lock,0,1)))
__attribute__((context(&info->lock,1,0)))
{
…
}

这些宏以双下划线__ 开头,表示它们是编译器环境的一部分。所有以一个或两个下划线开头的标识符都保留用于编译器环境实现。在 Linux 内核的情况下,因为 Linux 是一个不(因为它根本不可用)使用标准库的操作系统内核,所以它很自然地定义它自己的编译器环境定义,它是私​​有的。因此,两个下划线表示,这是编译器环境/实现特定的东西。

【讨论】:

  • 谢谢。够详细了。
【解决方案2】:

它们可能是用#define 定义的宏。您应该查找此类宏的定义并查看它们扩展为什么。它们可能会扩展为一些pragma,向编译器提供提示;它们可能会扩展为没有向开发人员或某些分析工具提供提示。含义可能不同

【讨论】:

  • 你可以在那个位置放一个宏??我不记得在 C 语法中你可以把任何东西放在那个位置。还有什么我可以放入那个pisition的吗?
  • 您可以将宏放在任何您想要的位置。当预处理器解析源文件时,它或多或少地使用其内容对宏进行查找和替换。它可能会扩展为空,这显然很好;它可能会扩展为一些编译指示,根据编译器的不同,这可能仍然没问题
【解决方案3】:

__attribute__ 这些宏评估为特定于编译器的功能。 man gcc 解释了一些用途。

前缀__ 通常用于避免名称冲突;双下划线作为前缀和后缀将标识符标记为由编译器本身使用。

有关 gcc 属性的更多信息,请参阅here

更多关于这些内核使用的信息可以在here找到。

【讨论】:

    【解决方案4】:

    这些是宏定义为

    # define __acquires(x)  __attribute__((context(x,0,1)))
    # define __releases(x)  __attribute__((context(x,1,0)))
    

    在 Linux/include/linux/compiler.h 中

    【讨论】:

    • 谢谢,最让我困惑的是他们的立场。我不记得你可以把东西放在那个位置。
    猜你喜欢
    • 1970-01-01
    • 2011-07-10
    • 2017-03-18
    • 1970-01-01
    • 1970-01-01
    • 2015-08-28
    • 2011-06-05
    • 2011-01-19
    • 2017-08-13
    相关资源
    最近更新 更多