【发布时间】:2011-04-15 13:47:06
【问题描述】:
虽然这个话题在这个论坛和所有其他论坛上已经讨论过很多次了,但我仍然有疑问。请帮忙。
do{} while(0) in 宏在 Linux 内核中是如何工作的?
例如,
#define preempt_disable() do { } while (0)
它如何禁用抢占?
#define might_resched() do { } while (0)
如何重新安排?
同样,我也看到了互斥锁和其他宏。这有什么帮助?我理解以下问题,但不理解上面的示例。
#define foo(x) do { do something } while(0)
编辑:
rt_mutex_lock 的以下代码呢?
/**
* rt_mutex_lock - lock a rt_mutex
*
* @lock: the rt_mutex to be locked
*/
void __sched rt_mutex_lock(struct rt_mutex *lock)
{
might_sleep();
rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, 0, rt_mutex_slowlock);
}
EXPORT_SYMBOL_GPL(rt_mutex_lock);
/*
* debug aware fast / slowpath lock,trylock,unlock
*
* The atomic acquire/release ops are compiled away, when either the
* architecture does not support cmpxchg or when debugging is enabled.
*/
static inline int rt_mutex_fastlock(struct rt_mutex *lock,
int state, int detect_deadlock, int (*slowfn)(struct rt_mutex *lock,
int state, struct hrtimer_sleeper *timeout, int detect_deadlock))
{
if (!detect_deadlock && likely(rt_mutex_cmpxchg(lock, NULL, current))) {
rt_mutex_deadlock_account_lock(lock, current);
return 0;
} else{
return slowfn(lock, state, NULL, detect_deadlock);
}
}
我很困惑,因为rt_mutex_deadlock_account_lock 在内核中的两个地方定义:
在kernel/rtmutex-debug.c:
void rt_mutex_deadlock_account_lock(struct rt_mutex *lock,
struct task_struct *task)
{
//....
}
在kernel/rtmutex.h:
#define rt_mutex_deadlock_account_lock(m, t) do { } while (0)
在 i2c 驱动程序中的新内核 2.6.35.4 中 rt_mutex_lock(&adap->bus_lock); 已替换 mutex_lock()。那这个怎么锁呢?
【问题讨论】:
-
在我看来它重新定义了该功能什么都不做。
-
@Mark:听起来很有说服力。 ravspratapsingh:对于上面的两个语句,我们是否理解正确,大括号之间真的没有任何内容?还是您只是这样简化了代码?
-
@paxdiablo:“可能的重复”并不是那么接近;它讨论了
do ... while (0),但代码在循环体内有动作——不像这里。所以这有点不同。 -
对我来说很清楚,内核作者有一些理由希望宏扩展为不仅仅是一个完全空的表达式,但使其扩展为空或只是一个注释似乎同样有用乍一看。无论如何,它导致 OP 在阅读内核源代码时对其提出质疑,因此我同意 @Jonathan 的观点,即更多的是缺少正文,而不是
do{}while(0)的含义。 -
@chiccodoro :这是来自内核的原始代码片段,没有任何修改。我担心的是,当 do-while(0) 什么都不做时,它实际上是如何锁定的。