pthread_rwlock_unlock.S 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /* Copyright (C) 2003, 2007 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, see
  13. <http://www.gnu.org/licenses/>. */
  14. #include <sysdep.h>
  15. #include <lowlevellock.h>
  16. #include <lowlevelrwlock.h>
  17. #include <bits/kernel-features.h>
  18. #include <tcb-offsets.h>
  19. #include "lowlevel-atomic.h"
  20. .text
  21. .globl __pthread_rwlock_unlock
  22. .type __pthread_rwlock_unlock,@function
  23. .protected __pthread_rwlock_unlock
  24. .align 5
  25. __pthread_rwlock_unlock:
  26. mov.l r12, @-r15
  27. mov.l r8, @-r15
  28. sts.l pr, @-r15
  29. mov r4, r8
  30. /* Get the lock. */
  31. mov #0, r3
  32. mov #1, r4
  33. #if MUTEX == 0
  34. CMPXCHG (r3, @r8, r4, r2)
  35. #else
  36. CMPXCHG (r3, @(MUTEX,r8), r4, r2)
  37. #endif
  38. bf 1f
  39. 2:
  40. mov.l @(WRITER,r8), r0
  41. tst r0, r0
  42. bf 5f
  43. mov.l @(NR_READERS,r8), r0
  44. add #-1, r0
  45. mov.l r0, @(NR_READERS,r8)
  46. tst r0, r0
  47. bf 6f
  48. 5:
  49. mov #0, r0
  50. mov.l r0, @(WRITER,r8)
  51. mov #1, r6
  52. mov r8, r4
  53. add #WRITERS_WAKEUP, r4
  54. mov.l @(WRITERS_QUEUED,r8), r0
  55. tst r0, r0
  56. bf 0f
  57. /* If also no readers waiting nothing to do. */
  58. mov.l @(READERS_QUEUED,r8), r0
  59. tst r0, r0
  60. bt 6f
  61. mov #-1, r6
  62. shlr r6 /* r6 = 0x7fffffff */
  63. mov r8, r4
  64. add #READERS_WAKEUP, r4
  65. 0:
  66. mov.l @r4, r0
  67. add #1, r0
  68. mov.l r0, @r4
  69. #if MUTEX == 0
  70. DEC (@r8, r2)
  71. #else
  72. DEC (@(MUTEX,r8), r2)
  73. #endif
  74. tst r2, r2
  75. bf 7f
  76. 8:
  77. #ifdef __ASSUME_PRIVATE_FUTEX
  78. mov #PSHARED, r0
  79. mov.b @(r0,r8), r5
  80. mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r0
  81. xor r0, r5
  82. extu.b r5, r5
  83. #else
  84. mov #PSHARED, r0
  85. mov.b @(r0,r8), r5
  86. extu.b r5, r5
  87. mov #FUTEX_WAKE, r0
  88. or r0, r5
  89. stc gbr, r1
  90. mov.w .Lpfoff, r2
  91. add r2, r1
  92. mov.l @r1, r0
  93. xor r0, r5
  94. #endif
  95. mov #SYS_futex, r3
  96. mov #0, r7
  97. extu.b r3, r3
  98. trapa #0x14
  99. SYSCALL_INST_PAD
  100. lds.l @r15+, pr
  101. mov.l @r15+, r8
  102. mov.l @r15+, r12
  103. rts
  104. mov #0, r0
  105. 6:
  106. #if MUTEX == 0
  107. DEC (@r8, r2)
  108. #else
  109. DEC (@(MUTEX,r8), r2)
  110. #endif
  111. tst r2, r2
  112. bf 3f
  113. 4:
  114. lds.l @r15+, pr
  115. mov.l @r15+, r8
  116. mov.l @r15+, r12
  117. rts
  118. mov #0, r0
  119. 1:
  120. mov r8, r5
  121. #if MUTEX != 0
  122. add #MUTEX, r5
  123. #endif
  124. mov #PSHARED, r0
  125. mov.b @(r0,r8), r6
  126. extu.b r6, r6
  127. mov.l .Lwait8, r1
  128. bsrf r1
  129. mov r2, r4
  130. .Lwait8b:
  131. bra 2b
  132. nop
  133. 3:
  134. mov r8, r4
  135. #if MUTEX != 0
  136. add #MUTEX, r4
  137. #endif
  138. mov #PSHARED, r0
  139. mov.b @(r0,r8), r5
  140. extu.b r5, r5
  141. mov.l .Lwake8, r1
  142. bsrf r1
  143. nop
  144. .Lwake8b:
  145. bra 4b
  146. nop
  147. 7:
  148. mov.l r4, @-r15
  149. mov.l r6, @-r15
  150. mov r8, r4
  151. #if MUTEX != 0
  152. add #MUTEX, r4
  153. #endif
  154. mov #PSHARED, r0
  155. mov.b @(r0,r8), r5
  156. extu.b r5, r5
  157. mov.l .Lwake9, r1
  158. bsrf r1
  159. nop
  160. .Lwake9b:
  161. mov.l @r15+, r6
  162. bra 8b
  163. mov.l @r15+, r4
  164. #ifndef __ASSUME_PRIVATE_FUTEX
  165. .Lpfoff:
  166. .word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
  167. #endif
  168. .align 2
  169. .Lwait8:
  170. .long __lll_lock_wait-.Lwait8b
  171. .Lwake8:
  172. .long __lll_unlock_wake-.Lwake8b
  173. .Lwake9:
  174. .long __lll_unlock_wake-.Lwake9b
  175. .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
  176. .globl pthread_rwlock_unlock
  177. pthread_rwlock_unlock = __pthread_rwlock_unlock
  178. .globl __pthread_rwlock_unlock_internal
  179. __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock