semaphore.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /* semaphore.h: semaphores for the FR-V
  2. *
  3. * Copyright (C) 2003 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. */
  11. #ifndef _ASM_SEMAPHORE_H
  12. #define _ASM_SEMAPHORE_H
  13. #define RW_LOCK_BIAS 0x01000000
  14. #ifndef __ASSEMBLY__
  15. #include <linux/linkage.h>
  16. #include <linux/wait.h>
  17. #include <linux/spinlock.h>
  18. #include <linux/rwsem.h>
  19. #define SEMAPHORE_DEBUG 0
  20. /*
  21. * the semaphore definition
  22. * - if counter is >0 then there are tokens available on the semaphore for down to collect
  23. * - if counter is <=0 then there are no spare tokens, and anyone that wants one must wait
  24. * - if wait_list is not empty, then there are processes waiting for the semaphore
  25. */
  26. struct semaphore {
  27. unsigned counter;
  28. spinlock_t wait_lock;
  29. struct list_head wait_list;
  30. #if SEMAPHORE_DEBUG
  31. unsigned __magic;
  32. #endif
  33. };
  34. #if SEMAPHORE_DEBUG
  35. # define __SEM_DEBUG_INIT(name) , (long)&(name).__magic
  36. #else
  37. # define __SEM_DEBUG_INIT(name)
  38. #endif
  39. #define __SEMAPHORE_INITIALIZER(name,count) \
  40. { count, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) __SEM_DEBUG_INIT(name) }
  41. #define __DECLARE_SEMAPHORE_GENERIC(name,count) \
  42. struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  43. #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
  44. #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
  45. static inline void sema_init (struct semaphore *sem, int val)
  46. {
  47. *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val);
  48. }
  49. static inline void init_MUTEX (struct semaphore *sem)
  50. {
  51. sema_init(sem, 1);
  52. }
  53. static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  54. {
  55. sema_init(sem, 0);
  56. }
  57. extern void __down(struct semaphore *sem, unsigned long flags);
  58. extern int __down_interruptible(struct semaphore *sem, unsigned long flags);
  59. extern void __up(struct semaphore *sem);
  60. static inline void down(struct semaphore *sem)
  61. {
  62. unsigned long flags;
  63. #if SEMAPHORE_DEBUG
  64. CHECK_MAGIC(sem->__magic);
  65. #endif
  66. spin_lock_irqsave(&sem->wait_lock, flags);
  67. if (likely(sem->counter > 0)) {
  68. sem->counter--;
  69. spin_unlock_irqrestore(&sem->wait_lock, flags);
  70. }
  71. else {
  72. __down(sem, flags);
  73. }
  74. }
  75. static inline int down_interruptible(struct semaphore *sem)
  76. {
  77. unsigned long flags;
  78. int ret = 0;
  79. #if SEMAPHORE_DEBUG
  80. CHECK_MAGIC(sem->__magic);
  81. #endif
  82. spin_lock_irqsave(&sem->wait_lock, flags);
  83. if (likely(sem->counter > 0)) {
  84. sem->counter--;
  85. spin_unlock_irqrestore(&sem->wait_lock, flags);
  86. }
  87. else {
  88. ret = __down_interruptible(sem, flags);
  89. }
  90. return ret;
  91. }
  92. /*
  93. * non-blockingly attempt to down() a semaphore.
  94. * - returns zero if we acquired it
  95. */
  96. static inline int down_trylock(struct semaphore *sem)
  97. {
  98. unsigned long flags;
  99. int success = 0;
  100. #if SEMAPHORE_DEBUG
  101. CHECK_MAGIC(sem->__magic);
  102. #endif
  103. spin_lock_irqsave(&sem->wait_lock, flags);
  104. if (sem->counter > 0) {
  105. sem->counter--;
  106. success = 1;
  107. }
  108. spin_unlock_irqrestore(&sem->wait_lock, flags);
  109. return !success;
  110. }
  111. static inline void up(struct semaphore *sem)
  112. {
  113. unsigned long flags;
  114. #if SEMAPHORE_DEBUG
  115. CHECK_MAGIC(sem->__magic);
  116. #endif
  117. spin_lock_irqsave(&sem->wait_lock, flags);
  118. if (!list_empty(&sem->wait_list))
  119. __up(sem);
  120. else
  121. sem->counter++;
  122. spin_unlock_irqrestore(&sem->wait_lock, flags);
  123. }
  124. static inline int sem_getcount(struct semaphore *sem)
  125. {
  126. return sem->counter;
  127. }
  128. #endif /* __ASSEMBLY__ */
  129. #endif