Why is the clear_bit() a specical bitop?

Parmenides mobile.parmenides at gmail.com
Wed Jul 13 17:57:07 EDT 2011


Hi,

When reading asm/bitops.h, I have some questions about bit clear operations.
p.s. the link: http://lxr.linux.no/linux+v2.6.34/arch/x86/include/asm/bitops.h

The clear_bit() is defined as follows:

/**
 * clear_bit - Clears a bit in memory
 * @nr: Bit to clear
 * @addr: Address to start counting from
 *
 * clear_bit() is atomic and may not be reordered.  However, it does
 * not contain a memory barrier, so if it is used for locking purposes,
 * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
 * in order to ensure changes are visible on other processors.
*/
static __always_inline void
clear_bit(int nr, volatile unsigned long *addr)
{
       if (IS_IMMEDIATE(nr)) {
               asm volatile(LOCK_PREFIX "andb %1,%0"
                       : CONST_MASK_ADDR(nr, addr)
                        : "iq" ((u8)~CONST_MASK(nr)));
        } else {
               asm volatile(LOCK_PREFIX "btr %1,%0"
                       : BITOP_ADDR(addr)
                       : "Ir" (nr));
       }
}

1. Two its parallel funcitons, namely set_bit() and change_bit()
contain their memory barriers, while the clear_bit() does not has one.
What does make it deserver such a special consideration?
2. How is it used for locking purpose?  Is there any example?

The clear_bit_unlock() is defined as follows:

/*
 * clear_bit_unlock - Clears a bit in memory
 * @nr: Bit to clear
 * @addr: Address to start counting from
 *
 * clear_bit() is atomic and implies release semantics before the memory
 * operation. It can be used for an unlock.
 */
static inline void clear_bit_unlock(unsigned nr, volatile unsigned long *addr)
{
       barrier();
       clear_bit(nr, addr);
}

3. "clear_bit() is atomic and implies ***release semantics*** before
the memory operation"
   What's the meaning of "release semantics"?
4. Why does the barrier() precede the clear_bit()? AFAIK, barrier()
will cause memory values reload into registers. Now that the
clear_bit() modifies the memory, why is there no a barrier() after the
clear_bit()?



More information about the Kernelnewbies mailing list