File: /Users/paulross/dev/linux/linux-3.13/include/linux/bit_spinlock.h

Green shading in the line number column means the source is part of the translation unit, red means it is conditionally excluded. Highlighted line numbers link to the translation unit page. Highlighted macros link to the macro page.

       1: #ifndef __LINUX_BIT_SPINLOCK_H
       2: #define __LINUX_BIT_SPINLOCK_H
       3: 
       4: #include <linux/kernel.h>
       5: #include <linux/preempt.h>
       6: #include <linux/atomic.h>
       7: #include <linux/bug.h>
       8: 
       9: /*
      10:  *  bit-based spin_lock()
      11:  *
      12:  * Don't use this unless you really need to: spin_lock() and spin_unlock()
      13:  * are significantly faster.
      14:  */
      15: static inline void bit_spin_lock(int bitnum, unsigned long *addr)
      16: {
      17:     /*
      18:      * Assuming the lock is uncontended, this never enters
      19:      * the body of the outer loop. If it is contended, then
      20:      * within the inner loop a non-atomic test is used to
      21:      * busywait with less bus contention for a good time to
      22:      * attempt to acquire the lock bit.
      23:      */
      24:     preempt_disable();
      25: #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
      26:     while (unlikely(test_and_set_bit_lock(bitnum, addr))) {
      27:         preempt_enable();
      28:         do {
      29:             cpu_relax();
      30:         } while (test_bit(bitnum, addr));
      31:         preempt_disable();
      32:     }
      33: #endif
      34:     __acquire(bitlock);
      35: }
      36: 
      37: /*
      38:  * Return true if it was acquired
      39:  */
      40: static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
      41: {
      42:     preempt_disable();
      43: #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
      44:     if (unlikely(test_and_set_bit_lock(bitnum, addr))) {
      45:         preempt_enable();
      46:         return 0;
      47:     }
      48: #endif
      49:     __acquire(bitlock);
      50:     return 1;
      51: }
      52: 
      53: /*
      54:  *  bit-based spin_unlock()
      55:  */
      56: static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
      57: {
      58: #ifdef CONFIG_DEBUG_SPINLOCK
      59:     BUG_ON(!test_bit(bitnum, addr));
      60: #endif
      61: #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
      62:     clear_bit_unlock(bitnum, addr);
      63: #endif
      64:     preempt_enable();
      65:     __release(bitlock);
      66: }
      67: 
      68: /*
      69:  *  bit-based spin_unlock()
      70:  *  non-atomic version, which can be used eg. if the bit lock itself is
      71:  *  protecting the rest of the flags in the word.
      72:  */
      73: static inline void __bit_spin_unlock(int bitnum, unsigned long *addr)
      74: {
      75: #ifdef CONFIG_DEBUG_SPINLOCK
      76:     BUG_ON(!test_bit(bitnum, addr));
      77: #endif
      78: #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
      79:     __clear_bit_unlock(bitnum, addr);
      80: #endif
      81:     preempt_enable();
      82:     __release(bitlock);
      83: }
      84: 
      85: /*
      86:  * Return true if the lock is held.
      87:  */
      88: static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
      89: {
      90: #if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
      91:     return test_bit(bitnum, addr);
      92: #elif defined CONFIG_PREEMPT_COUNT
      93:     return preempt_count();
      94: #else
      95:     return 1;
      96: #endif
      97: }
      98: 
      99: #endif /* __LINUX_BIT_SPINLOCK_H */
     100: 
     101: