Hi Julie, On Mon, Aug 1, 2011 at 2:28 PM, Julie Sullivan <kernelmail.jms@xxxxxxxxx> wrote: > Hi list, > > I'm looking at RCU at the moment and (on reading a recent article by > Paul McKenney on LWN) I've spotted something I'm a bit confused by in > this code, a function which is defined in kernel/rcutree_plugin.h: > > void __rcu_read_unlock(void) > { > struct task_struct *t = current; > > barrier(); /* needed if we ever invoke rcu_read_unlock in rcutree.c */ > --t->rcu_read_lock_nesting; > barrier(); /* decrement before load of ->rcu_read_unlock_special */ > if (t->rcu_read_lock_nesting == 0 && > unlikely(ACCESS_ONCE(t->rcu_read_unlock_special))) > rcu_read_unlock_special(t); > #ifdef CONFIG_PROVE_LOCKING > WARN_ON_ONCE(ACCESS_ONCE(t->rcu_read_lock_nesting) < 0); > #endif /* #ifdef CONFIG_PROVE_LOCKING */ > } > > Specifically, the conditional > > if (t->rcu_read_lock_nesting == 0 && > unlikely(ACCESS_ONCE(t->rcu_read_unlock_special))) > rcu_read_unlock_special(t); > > I've googled for 'likely/unlikely' and i've seen > > if (unlikely(... > > before in kernel code, and I might understand if the logical operator > here were || not &&, but why is the 'unlikely' attribute only applied > to the second operand here? Because both must be evaluated, with > left-to-right associativity, and then both must be true for the branch > to be taken, right? Yes - both must be true for the branch to be taken. However, if the first portion t->rcu_read_lock_nesting == 0 fails, then the unlikely portion won't be evaluated. C uses short-circuit evaluation for boolean expressions, whereas some other languages like Pascal would evaluate both sides of the && before determining the outcome. > If it's necessary for branch > prediction/optimization purposes shouldn't it be applied to both or > the first one? Maybe its neither likely nor unlikely? > Or might the operands also be re-ordered by the > compiler or processor so that the second is evaluated before the > first? C absolutely guarantees that the second will NEVER be evaluated before the first. Otherwise, things like this: if ( ptr && ptr->field ) could fail if ptr was NULL. -- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com _______________________________________________ Kernelnewbies mailing list Kernelnewbies@xxxxxxxxxxxxxxxxx http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies