semaphore.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef _M68K_SEMAPHORE_H
  2. #define _M68K_SEMAPHORE_H
  3. #define RW_LOCK_BIAS  0x01000000
  4. #ifndef __ASSEMBLY__
  5. #include <linux/linkage.h>
  6. #include <linux/wait.h>
  7. #include <linux/spinlock.h>
  8. #include <linux/rwsem.h>
  9. #include <linux/stringify.h>
  10. #include <asm/system.h>
  11. #include <asm/atomic.h>
  12. /*
  13.  * Interrupt-safe semaphores..
  14.  *
  15.  * (C) Copyright 1996 Linus Torvalds
  16.  *
  17.  * m68k version by Andreas Schwab
  18.  */
  19. struct semaphore {
  20. atomic_t count;
  21. atomic_t waking;
  22. wait_queue_head_t wait;
  23. #if WAITQUEUE_DEBUG
  24. long __magic;
  25. #endif
  26. };
  27. #if WAITQUEUE_DEBUG
  28. # define __SEM_DEBUG_INIT(name) 
  29. , (long)&(name).__magic
  30. #else
  31. # define __SEM_DEBUG_INIT(name)
  32. #endif
  33. #define __SEMAPHORE_INITIALIZER(name,count) 
  34. { ATOMIC_INIT(count), ATOMIC_INIT(0), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) 
  35. __SEM_DEBUG_INIT(name) }
  36. #define __MUTEX_INITIALIZER(name) 
  37. __SEMAPHORE_INITIALIZER(name,1)
  38. #define __DECLARE_SEMAPHORE_GENERIC(name,count) 
  39. struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)
  40. #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)
  41. #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0)
  42. extern inline void sema_init (struct semaphore *sem, int val)
  43. {
  44. *sem = (struct semaphore)__SEMAPHORE_INITIALIZER(*sem, val);
  45. }
  46. static inline void init_MUTEX (struct semaphore *sem)
  47. {
  48. sema_init(sem, 1);
  49. }
  50. static inline void init_MUTEX_LOCKED (struct semaphore *sem)
  51. {
  52. sema_init(sem, 0);
  53. }
  54. asmlinkage void __down_failed(void /* special register calling convention */);
  55. asmlinkage int  __down_failed_interruptible(void  /* params in registers */);
  56. asmlinkage int  __down_failed_trylock(void  /* params in registers */);
  57. asmlinkage void __up_wakeup(void /* special register calling convention */);
  58. asmlinkage void __down(struct semaphore * sem);
  59. asmlinkage int  __down_interruptible(struct semaphore * sem);
  60. asmlinkage int  __down_trylock(struct semaphore * sem);
  61. asmlinkage void __up(struct semaphore * sem);
  62. /*
  63.  * This is ugly, but we want the default case to fall through.
  64.  * "down_failed" is a special asm handler that calls the C
  65.  * routine that actually waits. See arch/m68k/lib/semaphore.S
  66.  */
  67. extern inline void down(struct semaphore * sem)
  68. {
  69. register struct semaphore *sem1 __asm__ ("%a1") = sem;
  70. #if WAITQUEUE_DEBUG
  71. CHECK_MAGIC(sem->__magic);
  72. #endif
  73. __asm__ __volatile__(
  74. "| atomic down operationnt"
  75. "subql #1,%0@nt"
  76. "jmi 2fnt"
  77. "1:n"
  78. ".subsection 1n"
  79. ".evenn"
  80. ".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "n"
  81. "_text_lock_" __stringify(KBUILD_BASENAME) ":n"
  82. ".endifn"
  83. "2:tpea 1bnt"
  84. "jbra __down_failedn"
  85. ".subsection 0n"
  86. : /* no outputs */
  87. : "a" (sem1)
  88. : "memory");
  89. }
  90. extern inline int down_interruptible(struct semaphore * sem)
  91. {
  92. register struct semaphore *sem1 __asm__ ("%a1") = sem;
  93. register int result __asm__ ("%d0");
  94. #if WAITQUEUE_DEBUG
  95. CHECK_MAGIC(sem->__magic);
  96. #endif
  97. __asm__ __volatile__(
  98. "| atomic interruptible down operationnt"
  99. "subql #1,%1@nt"
  100. "jmi 2fnt"
  101. "clrl %0n"
  102. "1:n"
  103. ".subsection 1n"
  104. ".evenn"
  105. ".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "n"
  106. "_text_lock_" __stringify(KBUILD_BASENAME) ":n"
  107. ".endifn"
  108. "2:tpea 1bnt"
  109. "jbra __down_failed_interruptiblen"
  110. ".subsection 0n"
  111. : "=d" (result)
  112. : "a" (sem1)
  113. : "memory");
  114. return result;
  115. }
  116. extern inline int down_trylock(struct semaphore * sem)
  117. {
  118. register struct semaphore *sem1 __asm__ ("%a1") = sem;
  119. register int result __asm__ ("%d0");
  120. #if WAITQUEUE_DEBUG
  121. CHECK_MAGIC(sem->__magic);
  122. #endif
  123. __asm__ __volatile__(
  124. "| atomic down trylock operationnt"
  125. "subql #1,%1@nt"
  126. "jmi 2fnt"
  127. "clrl %0n"
  128. "1:n"
  129. ".subsection 1n"
  130. ".evenn"
  131. ".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "n"
  132. "_text_lock_" __stringify(KBUILD_BASENAME) ":n"
  133. ".endifn"
  134. "2:tpea 1bnt"
  135. "jbra __down_failed_trylockn"
  136. ".subsection 0n"
  137. : "=d" (result)
  138. : "a" (sem1)
  139. : "memory");
  140. return result;
  141. }
  142. /*
  143.  * Note! This is subtle. We jump to wake people up only if
  144.  * the semaphore was negative (== somebody was waiting on it).
  145.  * The default case (no contention) will result in NO
  146.  * jumps for both down() and up().
  147.  */
  148. extern inline void up(struct semaphore * sem)
  149. {
  150. register struct semaphore *sem1 __asm__ ("%a1") = sem;
  151. #if WAITQUEUE_DEBUG
  152. CHECK_MAGIC(sem->__magic);
  153. #endif
  154. __asm__ __volatile__(
  155. "| atomic up operationnt"
  156. "addql #1,%0@nt"
  157. "jle 2fn"
  158. "1:n"
  159. ".subsection 1n"
  160. ".evenn"
  161. ".ifndef _text_lock_" __stringify(KBUILD_BASENAME) "n"
  162. "_text_lock_" __stringify(KBUILD_BASENAME) ":n"
  163. ".endifn"
  164. "2:t"
  165. "pea 1bnt"
  166. "jbra __up_wakeupn"
  167. ".subsection 0n"
  168. : /* no outputs */
  169. : "a" (sem1)
  170. : "memory");
  171. }
  172. #endif /* __ASSEMBLY__ */
  173. #endif