semaphore-helper.h 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #ifndef ASMARM_SEMAPHORE_HELPER_H
  2. #define ASMARM_SEMAPHORE_HELPER_H
  3. /*
  4. * These two _must_ execute atomically wrt each other.
  5. */
  6. static inline void wake_one_more(struct semaphore * sem)
  7. {
  8. unsigned long flags;
  9. spin_lock_irqsave(&semaphore_wake_lock, flags);
  10. if (atomic_read(&sem->count) <= 0)
  11. sem->waking++;
  12. spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  13. }
  14. static inline int waking_non_zero(struct semaphore *sem)
  15. {
  16. unsigned long flags;
  17. int ret = 0;
  18. spin_lock_irqsave(&semaphore_wake_lock, flags);
  19. if (sem->waking > 0) {
  20. sem->waking--;
  21. ret = 1;
  22. }
  23. spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  24. return ret;
  25. }
  26. /*
  27. * waking non zero interruptible
  28. * 1 got the lock
  29. * 0 go to sleep
  30. * -EINTR interrupted
  31. *
  32. * We must undo the sem->count down_interruptible() increment while we are
  33. * protected by the spinlock in order to make this atomic_inc() with the
  34. * atomic_read() in wake_one_more(), otherwise we can race. -arca
  35. */
  36. static inline int waking_non_zero_interruptible(struct semaphore *sem,
  37. struct task_struct *tsk)
  38. {
  39. unsigned long flags;
  40. int ret = 0;
  41. spin_lock_irqsave(&semaphore_wake_lock, flags);
  42. if (sem->waking > 0) {
  43. sem->waking--;
  44. ret = 1;
  45. } else if (signal_pending(tsk)) {
  46. atomic_inc(&sem->count);
  47. ret = -EINTR;
  48. }
  49. spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  50. return ret;
  51. }
  52. /*
  53. * waking_non_zero_try_lock:
  54. * 1 failed to lock
  55. * 0 got the lock
  56. *
  57. * We must undo the sem->count down_interruptible() increment while we are
  58. * protected by the spinlock in order to make this atomic_inc() with the
  59. * atomic_read() in wake_one_more(), otherwise we can race. -arca
  60. */
  61. static inline int waking_non_zero_trylock(struct semaphore *sem)
  62. {
  63. unsigned long flags;
  64. int ret = 1;
  65. spin_lock_irqsave(&semaphore_wake_lock, flags);
  66. if (sem->waking <= 0)
  67. atomic_inc(&sem->count);
  68. else {
  69. sem->waking--;
  70. ret = 0;
  71. }
  72. spin_unlock_irqrestore(&semaphore_wake_lock, flags);
  73. return ret;
  74. }
  75. #endif