c - spinlock_check()函数的使用

标签 c linux linux-device-driver spinlock

我对函数 spinlock_check() 有疑问用于 spin_lock_init() 宏。

下面是spinlock_check的代码,它返回rlock的地址

static __always_inline raw_spinlock_t *spinlock_check(spinlock_t *lock)
{
    return &lock->rlock;
}

它用在宏spin_lock_init中。该宏的代码:

#define spin_lock_init(_lock)               \
do {                            \
   spinlock_check(_lock);               \
   raw_spin_lock_init(&(_lock)->rlock);     \
} while (0)

我在 here 中看到了有关此主题的问题。 但我不太明白,想用我的方式表达疑惑。

spin_lock_init() 是一个宏,但 spinlock_check() 不是一个宏。它是一个内联函数。所以我认为这里不可能发生一些编译魔法,但我希望在执行这些指令期间会发生一些魔法。 spinlock_check() 有什么作用? 因为没有任何东西使用 spinlock_check() 函数的返回值。 即使 spinlock_check() 返回一些内容,下一步仍然会被执行。 因为我在其中一个文件中看到了它的用法,我认为它与 min(x, y) 宏不同。

这是我 found 的用法

#ifdef CONFIG_NUMA
static void do_numa_crng_init(struct work_struct *work)
{
    int i;
    struct crng_state *crng;
    struct crng_state **pool;

    pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
    for_each_online_node(i) {
        crng = kmalloc_node(sizeof(struct crng_state),
                    GFP_KERNEL | __GFP_NOFAIL, i);
        spin_lock_init(&crng->lock);
        crng_initialize(crng);
        pool[i] = crng;
    }
    mb();
    if (cmpxchg(&crng_node_pool, NULL, pool)) {
        for_each_node(i)
        kfree(pool[i]);
        kfree(pool);
    }
}

所以这里的crng是动态分配的。说我错过了 kmalloc 代码,这意味着我没有为 crng 分配内存,但我仍然使用了宏 spin_lock_init(crng)。 现在 spinlock_check() 函数有什么用呢? 不是在spinlock_check()函数raw_spin_lock_init之后自动执行吗?

如果要执行,那么spinlock_check()函数有什么用? 应该有一些意义,但我无法理解。

最佳答案

您缺少的是 spinlock_check() 不会在运行时执行任何检查。这就是它的返回值被忽略的原因。该指令预计会在编译期间被优化器删除。

那还有用吗?是的!其目的是确保在编译时其参数的类型为spinlock_t *。如果您不将指向 spinlock_t 的指针作为 spin_lock_init() 的参数提供,则会触发编译错误。

关于c - spinlock_check()函数的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52611817/

相关文章:

linux - 测试使用 VFIO 的用户空间驱动程序?

c - 如何在c中对矩阵(二维数组)进行排序?

c - 关于K&R中函数指针的问题

c - 读取 C 中的 .dat 文件丢失/重复记录

c - Linux 中的周期性任务

linux - 如何使用 bash 脚本翻转屏幕方向?

c - Linux 内核未将完整结构传递给 sysfs 回调

linux - 将基于 linux 的应用程序移植到 uC/OS-II 平台

c - 如何读取内核空间中关联的 uid 的 gids 列表?

linux - 等待队列与 Linux 中的信号量