semaphore.h 3.2 KB

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