虽然本论坛和所有其他论坛多次讨论过这个话题,但我仍有疑问.请帮忙.
do{} while(0)
in-macro 如何在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)
在新的内核2.6.35.4中,i2c驱动程序rt_mutex_lock(&adap->bus_lock);
已经取代了mutex_lock()
.这怎么锁定呢?
请参阅此链接以获得比我能给出的更好的解释.
@Kragen回答了做什么......虽然构造是为了 - 它基本上使得宏更安全使用.
但是,我不认为它回答了"这是如何工作的"这个问题:
#define preempt_disable() do { } while (0)
该宏被定义为什么都不做.你为什么什么都不想做?
在某些情况下,您希望使用宏作为占位符来执行某些操作.例如,您可以在一个系统上编写代码,其中"抢占"不是问题,但您知道代码可能被移植到"抢占"需要一些特殊处理的系统.因此,您可以在第二个系统需要的任何地方使用宏(以便稍后可以轻松启用),但是对于第一个系统,您可以将该宏定义为空白宏.
在某些情况下,您可能希望执行由不同部分组成的任务(例如START_TABLE(); TABLE_ENTRY(1); TABLE_ENTRY(2); END_TABLE();).这样可以很好地清理表格.但是你发现你实际上并不需要END_TABLE()宏.为了保持客户端代码整洁,您可以保留定义的宏,并将其定义为不执行任何操作.这样,所有表都有一个END_TABLE,代码更容易阅读.
类似的情况可能发生在两个状态(启用/禁用),其中一个状态需要宏来执行某些操作,但另一个状态只是默认情况下发生,因此一个状态的实现是"空的" - 您仍然使用宏,因为它使客户端代码更容易理解,因为它明确说明了启用或禁用事物的位置.