lowlevelrobustlock.S 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /* Copyright (C) 2002, 2003, 2004, 2006, 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 <pthread-errnos.h>
  17. #include <lowlevellock.h>
  18. #include <lowlevelrobustlock.h>
  19. #include <bits/kernel-features.h>
  20. #include <tls.h>
  21. .text
  22. #define FUTEX_WAITERS 0x80000000
  23. #define FUTEX_OWNER_DIED 0x40000000
  24. #ifdef __ASSUME_PRIVATE_FUTEX
  25. # define LOAD_FUTEX_WAIT(reg) \
  26. xorl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
  27. #else
  28. # if FUTEX_WAIT == 0
  29. # define LOAD_FUTEX_WAIT(reg) \
  30. xorl $FUTEX_PRIVATE_FLAG, reg ; \
  31. andl %gs:PRIVATE_FUTEX, reg
  32. # else
  33. # define LOAD_FUTEX_WAIT(reg) \
  34. xorl $FUTEX_PRIVATE_FLAG, reg ; \
  35. andl %gs:PRIVATE_FUTEX, reg ; \
  36. orl $FUTEX_WAIT, reg
  37. # endif
  38. #endif
  39. .globl __lll_robust_lock_wait
  40. .type __lll_robust_lock_wait,@function
  41. .hidden __lll_robust_lock_wait
  42. .align 16
  43. __lll_robust_lock_wait:
  44. cfi_startproc
  45. pushl %edx
  46. cfi_adjust_cfa_offset(4)
  47. pushl %ebx
  48. cfi_adjust_cfa_offset(4)
  49. pushl %esi
  50. cfi_adjust_cfa_offset(4)
  51. cfi_offset(%edx, -8)
  52. cfi_offset(%ebx, -12)
  53. cfi_offset(%esi, -16)
  54. movl %edx, %ebx
  55. xorl %esi, %esi /* No timeout. */
  56. LOAD_FUTEX_WAIT (%ecx)
  57. 4: movl %eax, %edx
  58. orl $FUTEX_WAITERS, %edx
  59. testl $FUTEX_OWNER_DIED, %eax
  60. jnz 3f
  61. cmpl %edx, %eax /* NB: %edx == 2 */
  62. je 1f
  63. LOCK
  64. cmpxchgl %edx, (%ebx)
  65. jnz 2f
  66. 1: movl $SYS_futex, %eax
  67. ENTER_KERNEL
  68. movl (%ebx), %eax
  69. 2: test %eax, %eax
  70. jne 4b
  71. movl %gs:TID, %edx
  72. orl $FUTEX_WAITERS, %edx
  73. LOCK
  74. cmpxchgl %edx, (%ebx)
  75. jnz 4b
  76. /* NB: %eax == 0 */
  77. 3: popl %esi
  78. cfi_adjust_cfa_offset(-4)
  79. cfi_restore(%esi)
  80. popl %ebx
  81. cfi_adjust_cfa_offset(-4)
  82. cfi_restore(%ebx)
  83. popl %edx
  84. cfi_adjust_cfa_offset(-4)
  85. cfi_restore(%edx)
  86. ret
  87. cfi_endproc
  88. .size __lll_robust_lock_wait,.-__lll_robust_lock_wait
  89. .globl __lll_robust_timedlock_wait
  90. .type __lll_robust_timedlock_wait,@function
  91. .hidden __lll_robust_timedlock_wait
  92. .align 16
  93. __lll_robust_timedlock_wait:
  94. cfi_startproc
  95. /* Check for a valid timeout value. */
  96. cmpl $1000000000, 4(%edx)
  97. jae 3f
  98. pushl %edi
  99. cfi_adjust_cfa_offset(4)
  100. pushl %esi
  101. cfi_adjust_cfa_offset(4)
  102. pushl %ebx
  103. cfi_adjust_cfa_offset(4)
  104. pushl %ebp
  105. cfi_adjust_cfa_offset(4)
  106. cfi_offset(%edi, -8)
  107. cfi_offset(%esi, -12)
  108. cfi_offset(%ebx, -16)
  109. cfi_offset(%ebp, -20)
  110. /* Stack frame for the timespec and timeval structs. */
  111. subl $12, %esp
  112. cfi_adjust_cfa_offset(12)
  113. movl %ecx, %ebp
  114. movl %edx, %edi
  115. 1: movl %eax, 8(%esp)
  116. /* Get current time. */
  117. movl %esp, %ebx
  118. xorl %ecx, %ecx
  119. movl $__NR_gettimeofday, %eax
  120. ENTER_KERNEL
  121. /* Compute relative timeout. */
  122. movl 4(%esp), %eax
  123. movl $1000, %edx
  124. mul %edx /* Milli seconds to nano seconds. */
  125. movl (%edi), %ecx
  126. movl 4(%edi), %edx
  127. subl (%esp), %ecx
  128. subl %eax, %edx
  129. jns 4f
  130. addl $1000000000, %edx
  131. subl $1, %ecx
  132. 4: testl %ecx, %ecx
  133. js 8f /* Time is already up. */
  134. /* Store relative timeout. */
  135. movl %ecx, (%esp)
  136. movl %edx, 4(%esp)
  137. movl %ebp, %ebx
  138. movl 8(%esp), %edx
  139. movl %edx, %eax
  140. orl $FUTEX_WAITERS, %edx
  141. testl $FUTEX_OWNER_DIED, %eax
  142. jnz 6f
  143. cmpl %eax, %edx
  144. je 2f
  145. LOCK
  146. cmpxchgl %edx, (%ebx)
  147. movl $0, %ecx /* Must use mov to avoid changing cc. */
  148. jnz 5f
  149. 2:
  150. /* Futex call. */
  151. movl %esp, %esi
  152. movl 20(%esp), %ecx
  153. LOAD_FUTEX_WAIT (%ecx)
  154. movl $SYS_futex, %eax
  155. ENTER_KERNEL
  156. movl %eax, %ecx
  157. movl (%ebx), %eax
  158. 5: testl %eax, %eax
  159. jne 7f
  160. movl %gs:TID, %edx
  161. orl $FUTEX_WAITERS, %edx
  162. LOCK
  163. cmpxchgl %edx, (%ebx)
  164. jnz 7f
  165. 6: addl $12, %esp
  166. cfi_adjust_cfa_offset(-12)
  167. popl %ebp
  168. cfi_adjust_cfa_offset(-4)
  169. cfi_restore(%ebp)
  170. popl %ebx
  171. cfi_adjust_cfa_offset(-4)
  172. cfi_restore(%ebx)
  173. popl %esi
  174. cfi_adjust_cfa_offset(-4)
  175. cfi_restore(%esi)
  176. popl %edi
  177. cfi_adjust_cfa_offset(-4)
  178. cfi_restore(%edi)
  179. ret
  180. 3: movl $EINVAL, %eax
  181. ret
  182. cfi_adjust_cfa_offset(28)
  183. cfi_offset(%edi, -8)
  184. cfi_offset(%esi, -12)
  185. cfi_offset(%ebx, -16)
  186. cfi_offset(%ebp, -20)
  187. /* Check whether the time expired. */
  188. 7: cmpl $-ETIMEDOUT, %ecx
  189. jne 1b
  190. 8: movl $ETIMEDOUT, %eax
  191. jmp 6b
  192. cfi_endproc
  193. .size __lll_robust_timedlock_wait,.-__lll_robust_timedlock_wait