c - how does do{} while(0) work in macro? -


though topic has been discussed many times in forum , other forums, still have doubts. please help.

how do{} while(0) in macro work in linux kernel? example,

#define preempt_disable()    { } while (0) 

how disable preempt?

#define might_resched()    { } while (0) 

how reschedule?

similarly have seen macros mutex locks , other also. how help? understand following problem not examples above.

#define foo(x)    { } while(0) 

edit:

what following code rt_mutex_lock?

/**  * rt_mutex_lock - lock rt_mutex  *  * @lock: rt_mutex 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  *  * atomic acquire/release ops compiled away, when either  * architecture not support cmpxchg or when debugging 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);         } } 

i confused because rt_mutex_deadlock_account_lock define @ 2 places in kernel:

in kernel/rtmutex-debug.c:

void rt_mutex_deadlock_account_lock(struct rt_mutex *lock,      struct task_struct *task) {     //.... } 

in kernel/rtmutex.h:

#define rt_mutex_deadlock_account_lock(m, t) { } while (0) 

in new kernel 2.6.35.4 in i2c driver rt_mutex_lock(&adap->bus_lock); has replaced mutex_lock(). how lock then?

@kragen has answered do...while construct - makes macro safer use.

however, don't think answers question of "how work?":

#define preempt_disable()    { } while (0) 

the macro defined do nothing. why want nothing?

  • in cases want use macro placeholder doing something. example, might write code on 1 system "preempt" isn't issue, know code might ported system "preempt" needs special handling. use macro everywhere second system needs (so handling easy enable later), first system define macro blank macro.

  • in cases may want things task made of different parts, (e.g. start_table(); table_entry(1); table_entry(2); end_table();). makes nice clean clear implementation of table. find don't need end_table() macro. keep client code tidy, leave macro defined, , define nothing. way, tables have end_table , code easier read.

  • a similar case can occur 2 states (enable/disable) 1 state needs macro something, other state happens default, implementation of 1 "empty" - still use macro because makes client code easier understand, because explicitly states places things enabled or disabled.


Comments

Popular posts from this blog

c++ - Convert big endian to little endian when reading from a binary file -

C#: Application without a window or taskbar item (background app) that can still use Console.WriteLine() -

unicode - Are email addresses allowed to contain non-alphanumeric characters? -