怎么做{} while(0)在宏中工作?

前端之家收集整理的这篇文章主要介绍了怎么做{} while(0)在宏中工作?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
虽然本论坛和所有其他论坛已经多次讨论过这个话题,但我仍有疑问.请帮忙.

Linux内核中,do {} while(0)如何工作?
例如,

#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,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,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,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驱动程序rt_mutex_lock(& adap-> bus_lock)中的新内核2.6.35.4中;已经取代了mutex_lock().这怎么锁定呢?

解决方法

@Kragen回答了做什么……虽然构造是为了 – 它基本上使宏更安全使用.

但是,我不认为它回答了“这是如何工作的?”的问题:

#define preempt_disable()    do { } while (0)

宏被定义为什么都不做.你为什么什么都不想做?

>在某些情况下,您希望使用宏作为占位符来执行某些操作.例如,您可以在一个系统上编写代码,其中“抢占”不是问题,但您知道代码可能被移植到“抢占”需要一些特殊处理的系统.因此,您在第二个系统需要的地方使用宏(以便稍后可以轻松启用),但是对于第一个系统,您可以将该宏定义为空白宏.>在某些情况下,您可能希望执行由不同部分组成的任务,(例如START_TABLE(); TABLE_ENTRY(1); TABLE_ENTRY(2); END_TABLE();).这样可以很好地清理表格.但是你发现你实际上并不需要END_TABLE()宏.为了使客户端代码保持整洁,您可以保留定义的宏,并将其定义为不执行任何操作.这样,所有表都有一个END_TABLE,代码更容易阅读.>类似的情况可能发生在两个状态(启用/禁用),其中一个状态需要宏来执行某些操作,但另一个状态只是默认情况下发生,因此一个状态的实现是“空的” – 您仍然使用宏,因为它使客户端代码更容易理解,因为它明确指出了启用或禁用事物的位置.

猜你在找的C&C++相关文章