pthread_rwlock_timedrdlock.S 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /* Copyright (C) 2002, 2003, 2007 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <sysdep.h>
  16. #include <lowlevellock.h>
  17. #include <lowlevelrwlock.h>
  18. #include <pthread-errnos.h>
  19. #include <bits/kernel-features.h>
  20. #include <tls.h>
  21. .text
  22. .globl pthread_rwlock_timedrdlock
  23. .type pthread_rwlock_timedrdlock,@function
  24. .align 16
  25. pthread_rwlock_timedrdlock:
  26. cfi_startproc
  27. pushl %esi
  28. cfi_adjust_cfa_offset(4)
  29. pushl %edi
  30. cfi_adjust_cfa_offset(4)
  31. pushl %ebx
  32. cfi_adjust_cfa_offset(4)
  33. pushl %ebp
  34. cfi_adjust_cfa_offset(4)
  35. cfi_offset(%esi, -8)
  36. cfi_offset(%edi, -12)
  37. cfi_offset(%ebx, -16)
  38. cfi_offset(%ebp, -20)
  39. subl $8, %esp
  40. cfi_adjust_cfa_offset(8)
  41. movl 28(%esp), %ebp
  42. movl 32(%esp), %edi
  43. /* Get the lock. */
  44. movl $1, %edx
  45. xorl %eax, %eax
  46. LOCK
  47. #if MUTEX == 0
  48. cmpxchgl %edx, (%ebp)
  49. #else
  50. cmpxchgl %edx, MUTEX(%ebp)
  51. #endif
  52. jnz 1f
  53. 2: movl WRITER(%ebp), %eax
  54. testl %eax, %eax
  55. jne 14f
  56. cmpl $0, WRITERS_QUEUED(%ebp)
  57. je 5f
  58. cmpb $0, FLAGS(%ebp)
  59. je 5f
  60. /* Check the value of the timeout parameter. */
  61. 3: cmpl $1000000000, 4(%edi)
  62. jae 19f
  63. addl $1, READERS_QUEUED(%ebp)
  64. je 4f
  65. movl READERS_WAKEUP(%ebp), %esi
  66. LOCK
  67. #if MUTEX == 0
  68. subl $1, (%ebp)
  69. #else
  70. subl $1, MUTEX(%ebp)
  71. #endif
  72. jne 10f
  73. /* Get current time. */
  74. 11: movl %esp, %ebx
  75. xorl %ecx, %ecx
  76. movl $__NR_gettimeofday, %eax
  77. ENTER_KERNEL
  78. /* Compute relative timeout. */
  79. movl 4(%esp), %eax
  80. movl $1000, %edx
  81. mul %edx /* Milli seconds to nano seconds. */
  82. movl (%edi), %ecx
  83. movl 4(%edi), %edx
  84. subl (%esp), %ecx
  85. subl %eax, %edx
  86. jns 15f
  87. addl $1000000000, %edx
  88. subl $1, %ecx
  89. 15: testl %ecx, %ecx
  90. js 16f /* Time is already up. */
  91. /* Futex call. */
  92. movl %ecx, (%esp) /* Store relative timeout. */
  93. movl %edx, 4(%esp)
  94. movl %esi, %edx
  95. #ifdef __ASSUME_PRIVATE_FUTEX
  96. movzbl PSHARED(%ebp), %ecx
  97. xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
  98. #else
  99. movzbl PSHARED(%ebp), %ecx
  100. # if FUTEX_WAIT != 0
  101. orl $FUTEX_WAIT, %ecx
  102. # endif
  103. xorl %gs:PRIVATE_FUTEX, %ecx
  104. #endif
  105. movl %esp, %esi
  106. leal READERS_WAKEUP(%ebp), %ebx
  107. movl $SYS_futex, %eax
  108. ENTER_KERNEL
  109. movl %eax, %esi
  110. 17:
  111. /* Reget the lock. */
  112. movl $1, %edx
  113. xorl %eax, %eax
  114. LOCK
  115. #if MUTEX == 0
  116. cmpxchgl %edx, (%ebp)
  117. #else
  118. cmpxchgl %edx, MUTEX(%ebp)
  119. #endif
  120. jnz 12f
  121. 13: subl $1, READERS_QUEUED(%ebp)
  122. cmpl $-ETIMEDOUT, %esi
  123. jne 2b
  124. 18: movl $ETIMEDOUT, %edx
  125. jmp 9f
  126. 5: xorl %edx, %edx
  127. addl $1, NR_READERS(%ebp)
  128. je 8f
  129. 9: LOCK
  130. #if MUTEX == 0
  131. subl $1, (%ebp)
  132. #else
  133. subl $1, MUTEX(%ebp)
  134. #endif
  135. jne 6f
  136. 7: movl %edx, %eax
  137. addl $8, %esp
  138. cfi_adjust_cfa_offset(-8)
  139. popl %ebp
  140. cfi_adjust_cfa_offset(-4)
  141. cfi_restore(%ebp)
  142. popl %ebx
  143. cfi_adjust_cfa_offset(-4)
  144. cfi_restore(%ebx)
  145. popl %edi
  146. cfi_adjust_cfa_offset(-4)
  147. cfi_restore(%edi)
  148. popl %esi
  149. cfi_adjust_cfa_offset(-4)
  150. cfi_restore(%esi)
  151. ret
  152. cfi_adjust_cfa_offset(24)
  153. cfi_offset(%esi, -8)
  154. cfi_offset(%edi, -12)
  155. cfi_offset(%ebx, -16)
  156. cfi_offset(%ebp, -20)
  157. 1:
  158. #if MUTEX == 0
  159. movl %ebp, %edx
  160. #else
  161. leal MUTEX(%ebp), %edx
  162. #endif
  163. movzbl PSHARED(%ebp), %ecx
  164. call __lll_lock_wait
  165. jmp 2b
  166. 14: cmpl %gs:TID, %eax
  167. jne 3b
  168. movl $EDEADLK, %edx
  169. jmp 9b
  170. 6:
  171. #if MUTEX == 0
  172. movl %ebp, %eax
  173. #else
  174. leal MUTEX(%ebp), %eax
  175. #endif
  176. movzbl PSHARED(%ebp), %ecx
  177. call __lll_unlock_wake
  178. jmp 7b
  179. /* Overflow. */
  180. 8: subl $1, NR_READERS(%ebp)
  181. movl $EAGAIN, %edx
  182. jmp 9b
  183. /* Overflow. */
  184. 4: subl $1, READERS_QUEUED(%ebp)
  185. movl $EAGAIN, %edx
  186. jmp 9b
  187. 10:
  188. #if MUTEX == 0
  189. movl %ebp, %eax
  190. #else
  191. leal MUTEX(%ebp), %eax
  192. #endif
  193. movzbl PSHARED(%ebp), %ecx
  194. call __lll_unlock_wake
  195. jmp 11b
  196. 12:
  197. #if MUTEX == 0
  198. movl %ebp, %edx
  199. #else
  200. leal MUTEX(%ebp), %edx
  201. #endif
  202. movzbl PSHARED(%ebp), %ecx
  203. call __lll_lock_wait
  204. jmp 13b
  205. 16: movl $-ETIMEDOUT, %esi
  206. jmp 17b
  207. 19: movl $EINVAL, %edx
  208. jmp 9b
  209. cfi_endproc
  210. .size pthread_rwlock_timedrdlock,.-pthread_rwlock_timedrdlock