semaphore.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
  29. static inline void sema_init(struct semaphore *sem, int val)
  30. {
  31. *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);
  32. }
  33. static inline void init_MUTEX (struct semaphore *sem)
  34. {
  35. sema_init(sem, 1);
  36. }
  37. static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  38. {
  39. sema_init(sem, 0);
  40. }
  41. extern void __down(struct semaphore * sem);
  42. extern int __down_interruptible(struct semaphore * sem);
  43. extern int __down_trylock(struct semaphore * sem);
  44. extern void __up(struct semaphore * sem);
  45. /* notice - we probably can do cli/sti here instead of saving */
  46. static inline void down(struct semaphore * sem)
  47. {
  48. unsigned long flags;
  49. int failed;
  50. might_sleep();
  51. /* atomically decrement the semaphores count, and if its negative, we wait */
  52. cris_atomic_save(sem, flags);
  53. failed = --(sem->count.counter) < 0;
  54. cris_atomic_restore(sem, flags);
  55. if(failed) {
  56. __down(sem);
  57. }
  58. }
  59. /*
  60. * This version waits in interruptible state so that the waiting
  61. * process can be killed. The down_interruptible routine
  62. * returns negative for signalled and zero for semaphore acquired.
  63. */
  64. static inline int down_interruptible(struct semaphore * sem)
  65. {
  66. unsigned long flags;
  67. int failed;
  68. might_sleep();
  69. /* atomically decrement the semaphores count, and if its negative, we wait */
  70. cris_atomic_save(sem, flags);
  71. failed = --(sem->count.counter) < 0;
  72. cris_atomic_restore(sem, flags);
  73. if(failed)
  74. failed = __down_interruptible(sem);
  75. return(failed);
  76. }
  77. static inline int down_trylock(struct semaphore * sem)
  78. {
  79. unsigned long flags;
  80. int failed;
  81. cris_atomic_save(sem, flags);
  82. failed = --(sem->count.counter) < 0;
  83. cris_atomic_restore(sem, flags);
  84. if(failed)
  85. failed = __down_trylock(sem);
  86. return(failed);
  87. }
  88. /*
  89. * Note! This is subtle. We jump to wake people up only if
  90. * the semaphore was negative (== somebody was waiting on it).
  91. * The default case (no contention) will result in NO
  92. * jumps for both down() and up().
  93. */
  94. static inline void up(struct semaphore * sem)
  95. {
  96. unsigned long flags;
  97. int wakeup;
  98. /* atomically increment the semaphores count, and if it was negative, we wake people */
  99. cris_atomic_save(sem, flags);
  100. wakeup = ++(sem->count.counter) <= 0;
  101. cris_atomic_restore(sem, flags);
  102. if(wakeup) {
  103. __up(sem);
  104. }
  105. }
  106. #endif