代码之家  ›  专栏  ›  技术社区  ›  ruach

何时应提供定义的宏来声明或初始化Linux内核中的变量?

  •  1
  • ruach  · 技术社区  · 6 年前

    似乎很多Linux内核组件都提供了宏来帮助程序员在运行时轻松地静态声明变量,该变量是在堆栈上分配的(并不意味着静态关键字);例如, DECLARE_WORK(name, void (*func)(void *), void *data) 用于声明用提供的func和数据参数初始化的工作结构。

    此外,有时它还提供一个宏来初始化动态创建的变量,例如 INIT_WORK(struct work_struct *work, void (*func)(void *), void *data) ,它将func和data参数分配给工作指针的成员字段。

    这些宏通常由核心内核组件定义,在驱动程序代码中不常见。是否有任何规则或自定义定义何时提供用于在Linux内核中声明或初始化数据结构(例如为常用数据结构提供此接口)的那些定义的宏?

    为什么要提供?这仅仅是因为通过给内核程序员提供一个干净的接口来声明和初始化复杂的数据结构来提供编写干净代码的方法吗?

    是因为有些数据结构是内部使用的,但有些数据结构可以被多个内核组件使用吗?换句话说,要隐藏数据结构的实现吗?

    0 回复  |  直到 6 年前
        1
  •  1
  •   th33lf    6 年前

    我觉得两者兼而有之。

    #define __WORK_INITIALIZER(n, f) {                  \
        .data = WORK_DATA_STATIC_INIT(),                \
        .entry  = { &(n).entry, &(n).entry },               \
        .func = (f),                            \
        __WORK_INIT_LOCKDEP_MAP(#n, &(n))               \
        }
    
    #define DECLARE_WORK(n, f)                      \
        struct work_struct n = __WORK_INITIALIZER(n, f)
    

    首先,在这种情况下,最可能的原因是初始化work结构至少需要4-5行代码,而且由于这是内核中经常发生的事情,它会给代码增加不必要的冗余,所以它被抽象成宏。它本可以是一个函数,但效率也较低。

    此外,内核开发人员和维护人员在检查代码时很难确保每次声明一个work_struct时,它也能正确初始化。在这种情况下,由于初始化代码位于同一个位置,因此可以安全地假设使用此宏的任何代码都将正确初始化结构。

    第三,您可能是在特定子系统中处理特定驱动程序的开发人员,可能不想知道内核工作队列机制的内部内容。您只希望能够使用提供的api对您的工作进行排队。此宏还可以避免您为内部操作而烦恼。即使明天将新字段添加到结构中供内部使用,也不需要更改驱动程序代码。