spinlock.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:2k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef __ASM_SPINLOCK_H
  2. #define __ASM_SPINLOCK_H
  3. #include <asm/system.h>
  4. /* Note that PA-RISC has to use `1' to mean unlocked and `0' to mean locked
  5.  * since it only has load-and-zero.
  6.  */
  7. #undef SPIN_LOCK_UNLOCKED
  8. #define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
  9. #define spin_lock_init(x) do { (x)->lock = 1; } while(0)
  10. #define spin_is_locked(x) ((x)->lock == 0)
  11. #define spin_unlock_wait(x) do { barrier(); } while(((volatile spinlock_t *)(x))->lock == 0)
  12. #if 1
  13. #define spin_lock(x) do { 
  14. while (__ldcw (&(x)->lock) == 0) 
  15. while (((x)->lock) == 0) ; } while (0)
  16. #else
  17. #define spin_lock(x) 
  18. do { while(__ldcw(&(x)->lock) == 0); } while(0)
  19. #endif
  20. #define spin_unlock(x) 
  21. do { (x)->lock = 1; } while(0)
  22. #define spin_trylock(x) (__ldcw(&(x)->lock) != 0)
  23. /*
  24.  * Read-write spinlocks, allowing multiple readers
  25.  * but only one writer.
  26.  */
  27. typedef struct {
  28. spinlock_t lock;
  29. volatile int counter;
  30. } rwlock_t;
  31. #define RW_LOCK_UNLOCKED (rwlock_t) { SPIN_LOCK_UNLOCKED, 0 }
  32. #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while (0)
  33. /* read_lock, read_unlock are pretty straightforward.  Of course it somehow
  34.  * sucks we end up saving/restoring flags twice for read_lock_irqsave aso. */
  35. static inline void read_lock(rwlock_t *rw)
  36. {
  37. unsigned long flags;
  38. spin_lock_irqsave(&rw->lock, flags);
  39. rw->counter++;
  40. spin_unlock_irqrestore(&rw->lock, flags);
  41. }
  42. static inline void read_unlock(rwlock_t *rw)
  43. {
  44. unsigned long flags;
  45. spin_lock_irqsave(&rw->lock, flags);
  46. rw->counter--;
  47. spin_unlock_irqrestore(&rw->lock, flags);
  48. }
  49. /* write_lock is less trivial.  We optimistically grab the lock and check
  50.  * if we surprised any readers.  If so we release the lock and wait till
  51.  * they're all gone before trying again
  52.  *
  53.  * Also note that we don't use the _irqsave / _irqrestore suffixes here.
  54.  * If we're called with interrupts enabled and we've got readers (or other
  55.  * writers) in interrupt handlers someone fucked up and we'd dead-lock
  56.  * sooner or later anyway.   prumpf */
  57. static inline void write_lock(rwlock_t *rw)
  58. {
  59. retry:
  60. spin_lock(&rw->lock);
  61. if(rw->counter != 0) {
  62. /* this basically never happens */
  63. spin_unlock(&rw->lock);
  64. while(rw->counter != 0);
  65. goto retry;
  66. }
  67. /* got it.  now leave without unlocking */
  68. }
  69. /* write_unlock is absolutely trivial - we don't have to wait for anything */
  70. static inline void write_unlock(rwlock_t *rw)
  71. {
  72. spin_unlock(&rw->lock);
  73. }
  74. #endif /* __ASM_SPINLOCK_H */