spinlock.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:2k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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