pthread_rwlock_unlock.S 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /* Copyright (C) 2003 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, write to the Free
  13. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  14. 02111-1307 USA. */
  15. #include <sysdep.h>
  16. #include <lowlevelrwlock.h>
  17. #include "lowlevel-atomic.h"
  18. #define FUTEX_WAIT 0
  19. #define FUTEX_WAKE 1
  20. .text
  21. .globl __pthread_rwlock_unlock
  22. .type __pthread_rwlock_unlock,@function
  23. .align 5
  24. __pthread_rwlock_unlock:
  25. mov.l r12, @-r15
  26. mov.l r8, @-r15
  27. sts.l pr, @-r15
  28. mov r4, r8
  29. /* Get the lock. */
  30. mov #0, r3
  31. mov #1, r4
  32. #if MUTEX == 0
  33. CMPXCHG (r3, @r8, r4, r2)
  34. #else
  35. CMPXCHG (r3, @(MUTEX,r8), r4, r2)
  36. #endif
  37. bf 1f
  38. 2:
  39. mov.l @(WRITER,r8), r0
  40. tst r0, r0
  41. bf 5f
  42. mov.l @(NR_READERS,r8), r0
  43. add #-1, r0
  44. mov.l r0, @(NR_READERS,r8)
  45. tst r0, r0
  46. bf 6f
  47. 5:
  48. mov #0, r0
  49. mov.l r0, @(WRITER,r8)
  50. mov #1, r6
  51. mov r8, r4
  52. add #WRITERS_WAKEUP, r4
  53. mov.l @(WRITERS_QUEUED,r8), r0
  54. tst r0, r0
  55. bf 0f
  56. /* If also no readers waiting nothing to do. */
  57. mov.l @(READERS_QUEUED,r8), r0
  58. tst r0, r0
  59. bt 6f
  60. mov #-1, r6
  61. shlr r6 /* r6 = 0x7fffffff */
  62. mov r8, r4
  63. add #READERS_WAKEUP, r4
  64. 0:
  65. mov.l @r4, r0
  66. add #1, r0
  67. mov.l r0, @r4
  68. #if MUTEX == 0
  69. DEC (@r8, r2)
  70. #else
  71. DEC (@(MUTEX,r8), r2)
  72. #endif
  73. tst r2, r2
  74. bf 7f
  75. 8:
  76. mov #FUTEX_WAKE, r5
  77. mov #SYS_futex, r3
  78. mov #0, r7
  79. extu.b r3, r3
  80. trapa #0x14
  81. SYSCALL_INST_PAD
  82. lds.l @r15+, pr
  83. mov.l @r15+, r8
  84. mov.l @r15+, r12
  85. rts
  86. mov #0, r0
  87. 6:
  88. #if MUTEX == 0
  89. DEC (@r8, r2)
  90. #else
  91. DEC (@(MUTEX,r8), r2)
  92. #endif
  93. tst r2, r2
  94. bf 3f
  95. 4:
  96. lds.l @r15+, pr
  97. mov.l @r15+, r8
  98. mov.l @r15+, r12
  99. rts
  100. mov #0, r0
  101. 1:
  102. mov r8, r5
  103. #if MUTEX != 0
  104. add #MUTEX, r5
  105. #endif
  106. mov r2, r4
  107. mov.l .Lwait8, r1
  108. bsrf r1
  109. nop
  110. .Lwait8b:
  111. bra 2b
  112. nop
  113. 3:
  114. mov r8, r4
  115. #if MUTEX != 0
  116. add #MUTEX, r4
  117. #endif
  118. mov.l .Lwake8, r1
  119. bsrf r1
  120. nop
  121. .Lwake8b:
  122. bra 4b
  123. nop
  124. 7:
  125. mov.l r4, @-r15
  126. mov.l r6, @-r15
  127. mov r8, r4
  128. #if MUTEX != 0
  129. add #MUTEX, r4
  130. #endif
  131. mov.l .Lwake9, r1
  132. bsrf r1
  133. nop
  134. .Lwake9b:
  135. mov.l @r15+, r6
  136. bra 8b
  137. mov.l @r15+, r4
  138. .align 2
  139. .Lwait8:
  140. .long __lll_mutex_lock_wait-.Lwait8b
  141. .Lwake8:
  142. .long __lll_mutex_unlock_wake-.Lwake8b
  143. .Lwake9:
  144. .long __lll_mutex_unlock_wake-.Lwake9b
  145. .size __pthread_rwlock_unlock,.-__pthread_rwlock_unlock
  146. .globl pthread_rwlock_unlock
  147. pthread_rwlock_unlock = __pthread_rwlock_unlock
  148. .globl __pthread_rwlock_unlock_internal
  149. __pthread_rwlock_unlock_internal = __pthread_rwlock_unlock