semaphore.h 3.2 KB

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