sem_timedwait.S 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /* Copyright (C) 2002, 2003, 2004, 2005 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 <tcb-offsets.h>
  19. #ifndef UP
  20. # define LOCK lock
  21. #else
  22. # define
  23. #endif
  24. #define FUTEX_WAKE 1
  25. .text
  26. .globl sem_timedwait
  27. .type sem_timedwait,@function
  28. .align 16
  29. cfi_startproc
  30. sem_timedwait:
  31. /* First check for cancellation. */
  32. movl %gs:CANCELHANDLING, %eax
  33. andl $0xfffffff9, %eax
  34. cmpl $8, %eax
  35. je 10f
  36. movl 4(%esp), %ecx
  37. movl (%ecx), %eax
  38. 2: testl %eax, %eax
  39. je,pn 1f
  40. leal -1(%eax), %edx
  41. LOCK
  42. cmpxchgl %edx, (%ecx)
  43. jne,pn 2b
  44. xorl %eax, %eax
  45. ret
  46. /* Check whether the timeout value is valid. */
  47. 1: pushl %esi
  48. cfi_adjust_cfa_offset(4)
  49. pushl %edi
  50. cfi_adjust_cfa_offset(4)
  51. pushl %ebx
  52. cfi_adjust_cfa_offset(4)
  53. subl $12, %esp
  54. cfi_adjust_cfa_offset(12)
  55. movl 32(%esp), %edi
  56. cfi_offset(7, -12) /* %edi */
  57. /* Check for invalid nanosecond field. */
  58. cmpl $1000000000, 4(%edi)
  59. movl $EINVAL, %esi
  60. cfi_offset(6, -8) /* %esi */
  61. jae 6f
  62. cfi_offset(3, -16) /* %ebx */
  63. 7: call __pthread_enable_asynccancel
  64. movl %eax, 8(%esp)
  65. xorl %ecx, %ecx
  66. movl %esp, %ebx
  67. movl %ecx, %edx
  68. movl $SYS_gettimeofday, %eax
  69. ENTER_KERNEL
  70. /* Compute relative timeout. */
  71. movl 4(%esp), %eax
  72. movl $1000, %edx
  73. mul %edx /* Milli seconds to nano seconds. */
  74. movl (%edi), %ecx
  75. movl 4(%edi), %edx
  76. subl (%esp), %ecx
  77. subl %eax, %edx
  78. jns 5f
  79. addl $1000000000, %edx
  80. subl $1, %ecx
  81. 5: testl %ecx, %ecx
  82. movl $ETIMEDOUT, %esi
  83. js 6f /* Time is already up. */
  84. movl %ecx, (%esp) /* Store relative timeout. */
  85. movl %edx, 4(%esp)
  86. movl 28(%esp), %ebx
  87. xorl %ecx, %ecx
  88. movl %esp, %esi
  89. movl $SYS_futex, %eax
  90. xorl %edx, %edx
  91. ENTER_KERNEL
  92. movl %eax, %esi
  93. movl 8(%esp), %eax
  94. call __pthread_disable_asynccancel
  95. testl %esi, %esi
  96. je,pt 9f
  97. cmpl $-EWOULDBLOCK, %esi
  98. jne 3f
  99. 9: movl (%ebx), %eax
  100. 8: testl %eax, %eax
  101. je 7b
  102. leal -1(%eax), %ecx
  103. LOCK
  104. cmpxchgl %ecx, (%ebx)
  105. jne,pn 8b
  106. addl $12, %esp
  107. cfi_adjust_cfa_offset(-12)
  108. xorl %eax, %eax
  109. popl %ebx
  110. cfi_adjust_cfa_offset(-4)
  111. cfi_restore(3)
  112. popl %edi
  113. cfi_adjust_cfa_offset(-4)
  114. cfi_restore(7)
  115. popl %esi
  116. cfi_adjust_cfa_offset(-4)
  117. cfi_restore(6)
  118. ret
  119. cfi_adjust_cfa_offset(24)
  120. cfi_offset(6, -8) /* %esi */
  121. cfi_offset(7, -12) /* %edi */
  122. cfi_offset(3, -16) /* %ebx */
  123. 3: negl %esi
  124. 6:
  125. #ifdef PIC
  126. call __i686.get_pc_thunk.bx
  127. #else
  128. movl $4f, %ebx
  129. 4:
  130. #endif
  131. addl $_GLOBAL_OFFSET_TABLE_, %ebx
  132. #if USE___THREAD
  133. # ifdef NO_TLS_DIRECT_SEG_REFS
  134. movl errno@gotntpoff(%ebx), %edx
  135. addl %gs:0, %edx
  136. movl %esi, (%edx)
  137. # else
  138. movl errno@gotntpoff(%ebx), %edx
  139. movl %esi, %gs:(%edx)
  140. # endif
  141. #else
  142. call __errno_location@plt
  143. movl %esi, (%eax)
  144. #endif
  145. addl $12, %esp
  146. cfi_adjust_cfa_offset(-12)
  147. orl $-1, %eax
  148. popl %ebx
  149. cfi_adjust_cfa_offset(-4)
  150. cfi_restore(3)
  151. popl %edi
  152. cfi_adjust_cfa_offset(-4)
  153. cfi_restore(7)
  154. popl %esi
  155. cfi_adjust_cfa_offset(-4)
  156. cfi_restore(6)
  157. ret
  158. 10: /* Canceled. */
  159. movl $0xffffffff, %gs:RESULT
  160. LOCK
  161. orl $0x10, %gs:CANCELHANDLING
  162. movl %gs:CLEANUP_JMP_BUF, %eax
  163. jmp HIDDEN_JUMPTARGET (__pthread_unwind)
  164. cfi_endproc
  165. .size sem_timedwait,.-sem_timedwait