lowlevelrobustlock.S 4.7 KB

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