semaphore.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* $Id: semaphore.h,v 1.3 2001/05/08 13:54:09 bjornw Exp $ */
  2. /* On the i386 these are coded in asm, perhaps we should as well. Later.. */
  3. #ifndef _CRIS_SEMAPHORE_H
  4. #define _CRIS_SEMAPHORE_H
  5. #define RW_LOCK_BIAS 0x01000000
  6. #include <linux/wait.h>
  7. #include <linux/spinlock.h>
  8. #include <linux/rwsem.h>
  9. #include <asm/system.h>
  10. #include <asm/atomic.h>
  11. /*
  12. * CRIS semaphores, implemented in C-only so far.
  13. */
  14. struct semaphore {
  15. atomic_t count;
  16. atomic_t waking;
  17. wait_queue_head_t wait;
  18. };
  19. #define __SEMAPHORE_INITIALIZER(name, n) \
  20. { \
  21. .count = ATOMIC_INIT(n), \
  22. .waking = ATOMIC_INIT(0), \
  23. .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \
  24. }
  25. #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
  26. struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  27. #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
  28. static inline void sema_init(struct semaphore *sem, int val)
  29. {
  30. *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
  31. }
  32. static inline void init_MUTEX (struct semaphore *sem)
  33. {
  34. sema_init(sem, 1);
  35. }
  36. static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  37. {
  38. sema_init(sem, 0);
  39. }
  40. extern void __down(struct semaphore * sem);
  41. extern int __down_interruptible(struct semaphore * sem);
  42. extern int __down_trylock(struct semaphore * sem);
  43. extern void __up(struct semaphore * sem);
  44. /* notice - we probably can do cli/sti here instead of saving */
  45. static inline void down(struct semaphore * sem)
  46. {
  47. unsigned long flags;
  48. int failed;
  49. might_sleep();
  50. /* atomically decrement the semaphores count, and if its negative, we wait */
  51. cris_atomic_save(sem, flags);
  52. failed = --(sem->count.counter) < 0;
  53. cris_atomic_restore(sem, flags);
  54. if(failed) {
  55. __down(sem);
  56. }
  57. }
  58. /*
  59. * This version waits in interruptible state so that the waiting
  60. * process can be killed. The down_interruptible routine
  61. * returns negative for signalled and zero for semaphore acquired.
  62. */
  63. static inline int down_interruptible(struct semaphore * sem)
  64. {
  65. unsigned long flags;
  66. int failed;
  67. might_sleep();
  68. /* atomically decrement the semaphores count, and if its negative, we wait */
  69. cris_atomic_save(sem, flags);
  70. failed = --(sem->count.counter) < 0;
  71. cris_atomic_restore(sem, flags);
  72. if(failed)
  73. failed = __down_interruptible(sem);
  74. return(failed);
  75. }
  76. static inline int down_trylock(struct semaphore * sem)
  77. {
  78. unsigned long flags;
  79. int failed;
  80. cris_atomic_save(sem, flags);
  81. failed = --(sem->count.counter) < 0;
  82. cris_atomic_restore(sem, flags);
  83. if(failed)
  84. failed = __down_trylock(sem);
  85. return(failed);
  86. }
  87. /*
  88. * Note! This is subtle. We jump to wake people up only if
  89. * the semaphore was negative (== somebody was waiting on it).
  90. * The default case (no contention) will result in NO
  91. * jumps for both down() and up().
  92. */
  93. static inline void up(struct semaphore * sem)
  94. {
  95. unsigned long flags;
  96. int wakeup;
  97. /* atomically increment the semaphores count, and if it was negative, we wake people */
  98. cris_atomic_save(sem, flags);
  99. wakeup = ++(sem->count.counter) <= 0;
  100. cris_atomic_restore(sem, flags);
  101. if(wakeup) {
  102. __up(sem);
  103. }
  104. }
  105. #endif