pthread_rwlock_timedwrlock.S 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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, write to the Free
  14. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  15. 02111-1307 USA. */
  16. #include <sysdep.h>
  17. #include <lowlevellock.h>
  18. #include <lowlevelrwlock.h>
  19. #include <pthread-errnos.h>
  20. #include <bits/kernel-features.h>
  21. #include <tls.h>
  22. .text
  23. .globl pthread_rwlock_timedwrlock
  24. .type pthread_rwlock_timedwrlock,@function
  25. .align 16
  26. pthread_rwlock_timedwrlock:
  27. cfi_startproc
  28. pushl %esi
  29. cfi_adjust_cfa_offset(4)
  30. pushl %edi
  31. cfi_adjust_cfa_offset(4)
  32. pushl %ebx
  33. cfi_adjust_cfa_offset(4)
  34. pushl %ebp
  35. cfi_adjust_cfa_offset(4)
  36. cfi_offset(%esi, -8)
  37. cfi_offset(%edi, -12)
  38. cfi_offset(%ebx, -16)
  39. cfi_offset(%ebp, -20)
  40. subl $8, %esp
  41. cfi_adjust_cfa_offset(8)
  42. movl 28(%esp), %ebp
  43. movl 32(%esp), %edi
  44. /* Get the lock. */
  45. movl $1, %edx
  46. xorl %eax, %eax
  47. LOCK
  48. #if MUTEX == 0
  49. cmpxchgl %edx, (%ebp)
  50. #else
  51. cmpxchgl %edx, MUTEX(%ebp)
  52. #endif
  53. jnz 1f
  54. 2: movl WRITER(%ebp), %eax
  55. testl %eax, %eax
  56. jne 14f
  57. cmpl $0, NR_READERS(%ebp)
  58. je 5f
  59. /* Check the value of the timeout parameter. */
  60. 3: cmpl $1000000000, 4(%edi)
  61. jae 19f
  62. addl $1, WRITERS_QUEUED(%ebp)
  63. je 4f
  64. movl WRITERS_WAKEUP(%ebp), %esi
  65. LOCK
  66. #if MUTEX == 0
  67. subl $1, (%ebp)
  68. #else
  69. subl $1, MUTEX(%ebp)
  70. #endif
  71. jne 10f
  72. /* Get current time. */
  73. 11: movl %esp, %ebx
  74. xorl %ecx, %ecx
  75. movl $__NR_gettimeofday, %eax
  76. ENTER_KERNEL
  77. /* Compute relative timeout. */
  78. movl 4(%esp), %eax
  79. movl $1000, %edx
  80. mul %edx /* Milli seconds to nano seconds. */
  81. movl (%edi), %ecx
  82. movl 4(%edi), %edx
  83. subl (%esp), %ecx
  84. subl %eax, %edx
  85. jns 15f
  86. addl $1000000000, %edx
  87. subl $1, %ecx
  88. 15: testl %ecx, %ecx
  89. js 16f /* Time is already up. */
  90. /* Futex call. */
  91. movl %ecx, (%esp) /* Store relative timeout. */
  92. movl %edx, 4(%esp)
  93. movl %esi, %edx
  94. #ifdef __ASSUME_PRIVATE_FUTEX
  95. movzbl PSHARED(%ebp), %ecx
  96. xorl $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
  97. #else
  98. movzbl PSHARED(%ebp), %ecx
  99. # if FUTEX_WAIT != 0
  100. orl $FUTEX_WAIT, %ecx
  101. # endif
  102. xorl %gs:PRIVATE_FUTEX, %ecx
  103. #endif
  104. movl %esp, %esi
  105. leal WRITERS_WAKEUP(%ebp), %ebx
  106. movl $SYS_futex, %eax
  107. ENTER_KERNEL
  108. movl %eax, %esi
  109. 17:
  110. /* Reget the lock. */
  111. movl $1, %edx
  112. xorl %eax, %eax
  113. LOCK
  114. #if MUTEX == 0
  115. cmpxchgl %edx, (%ebp)
  116. #else
  117. cmpxchgl %edx, MUTEX(%ebp)
  118. #endif
  119. jnz 12f
  120. 13: subl $1, WRITERS_QUEUED(%ebp)
  121. cmpl $-ETIMEDOUT, %esi
  122. jne 2b
  123. 18: movl $ETIMEDOUT, %edx
  124. jmp 9f
  125. 5: xorl %edx, %edx
  126. movl %gs:TID, %eax
  127. movl %eax, WRITER(%ebp)
  128. 9: LOCK
  129. #if MUTEX == 0
  130. subl $1, (%ebp)
  131. #else
  132. subl $1, MUTEX(%ebp)
  133. #endif
  134. jne 6f
  135. 7: movl %edx, %eax
  136. addl $8, %esp
  137. cfi_adjust_cfa_offset(-8)
  138. popl %ebp
  139. cfi_adjust_cfa_offset(-4)
  140. cfi_restore(%ebp)
  141. popl %ebx
  142. cfi_adjust_cfa_offset(-4)
  143. cfi_restore(%ebx)
  144. popl %edi
  145. cfi_adjust_cfa_offset(-4)
  146. cfi_restore(%edi)
  147. popl %esi
  148. cfi_adjust_cfa_offset(-4)
  149. cfi_restore(%esi)
  150. ret
  151. cfi_adjust_cfa_offset(24)
  152. cfi_offset(%esi, -8)
  153. cfi_offset(%edi, -12)
  154. cfi_offset(%ebx, -16)
  155. cfi_offset(%ebp, -20)
  156. 1:
  157. #if MUTEX == 0
  158. movl %ebp, %edx
  159. #else
  160. leal MUTEX(%ebp), %edx
  161. #endif
  162. movzbl PSHARED(%ebp), %ecx
  163. call __lll_lock_wait
  164. jmp 2b
  165. 14: cmpl %gs:TID, %eax
  166. jne 3b
  167. 20: movl $EDEADLK, %edx
  168. jmp 9b
  169. 6:
  170. #if MUTEX == 0
  171. movl %ebp, %eax
  172. #else
  173. leal MUTEX(%ebp), %eax
  174. #endif
  175. movzbl PSHARED(%ebp), %ecx
  176. call __lll_unlock_wake
  177. jmp 7b
  178. /* Overflow. */
  179. 4: subl $1, WRITERS_QUEUED(%ebp)
  180. movl $EAGAIN, %edx
  181. jmp 9b
  182. 10:
  183. #if MUTEX == 0
  184. movl %ebp, %eax
  185. #else
  186. leal MUTEX(%ebp), %eax
  187. #endif
  188. movzbl PSHARED(%ebp), %ecx
  189. call __lll_unlock_wake
  190. jmp 11b
  191. 12:
  192. #if MUTEX == 0
  193. movl %ebp, %edx
  194. #else
  195. leal MUTEX(%ebp), %edx
  196. #endif
  197. movzbl PSHARED(%ebp), %ecx
  198. call __lll_lock_wait
  199. jmp 13b
  200. 16: movl $-ETIMEDOUT, %esi
  201. jmp 17b
  202. 19: movl $EINVAL, %edx
  203. jmp 9b
  204. cfi_endproc
  205. .size pthread_rwlock_timedwrlock,.-pthread_rwlock_timedwrlock