自旋锁初始化函数

mip*_*mip 1 c mutex linux-kernel

要在内核 v4.19-rc5 中初始化自旋锁,必须使用spin_lock_init如下定义的宏:

#define spin_lock_init(_lock)               \
do {    \
       spinlock_check(_lock);               \
       raw_spin_lock_init(&(_lock)->rlock);     \
} while (0)
Run Code Online (Sandbox Code Playgroud)

该函数spinlock_check(_lock)只是返回&lock->rlock本文解释说:

spinlock_check 的实现非常简单,这个函数只是返回给定自旋锁的 raw_spinlock_t 以确保我们得到完全正常的原始自旋锁
我不明白这个函数如何执行检查。我期待ifcckeck 函数中的一些语句。抱歉,我是内核编程新手。

小智 5

它不需要任何if语句,因为它的存在是为了编译时检查。

您可以在这里看到大多数自旋锁操作都定义为宏,因此它们无法限制其参数的类型。

考虑以下示例:

struct not_a_spinlock {
    raw_spinlock_t rlock;
};
Run Code Online (Sandbox Code Playgroud)

如果没有spinlock_check我可以使用spin_lock_init它来初始化它:

struct not_a_spinlock spin;
spin_lock_init(&spin);
Run Code Online (Sandbox Code Playgroud)

但由于spinlock_check,这将行不通。这使得这些宏受到类型限制,因此它们的行为更像函数。

它返回的原因&lock->rlock是为了方便——它的返回值可以传递给下一个函数。

因此,值得将示例中的宏重写为:

#define spin_lock_init(_lock)                         \
do {                                                  \
       raw_spin_lock_init(spinlock_check(_lock));     \
} while (0)
Run Code Online (Sandbox Code Playgroud)

类似的技术可以与宏一起使用,以在一定程度上限制它们的参数类型,如下所示

#define min(x, y) ({                \
    typeof(x) _min1 = (x);          \
    typeof(y) _min2 = (y);          \
    (void) (&_min1 == &_min2);      \
    _min1 < _min2 ? _min1 : _min2; })
Run Code Online (Sandbox Code Playgroud)