home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / include / linux / bit_spinlock.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  2.2 KB  |  96 lines

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