sem_timedwait.S 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /* Copyright (C) 2002, 2003, 2004, 2005, 2007, 2009 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 <structsem.h>
  18. #include <lowlevellock.h>
  19. #if VALUE != 0
  20. # error "code needs to be rewritten for VALUE != 0"
  21. #endif
  22. .text
  23. .globl sem_timedwait
  24. .type sem_timedwait,@function
  25. .align 16
  26. sem_timedwait:
  27. .LSTARTCODE:
  28. movl 4(%esp), %ecx
  29. movl (%ecx), %eax
  30. 2: testl %eax, %eax
  31. je 1f
  32. leal -1(%eax), %edx
  33. LOCK
  34. cmpxchgl %edx, (%ecx)
  35. jne 2b
  36. xorl %eax, %eax
  37. ret
  38. /* Check whether the timeout value is valid. */
  39. 1: pushl %esi
  40. .Lpush_esi:
  41. pushl %edi
  42. .Lpush_edi:
  43. pushl %ebx
  44. .Lpush_ebx:
  45. subl $12, %esp
  46. .Lsub_esp:
  47. movl 32(%esp), %edi
  48. /* Check for invalid nanosecond field. */
  49. cmpl $1000000000, 4(%edi)
  50. movl $EINVAL, %esi
  51. jae 6f
  52. LOCK
  53. incl NWAITERS(%ecx)
  54. 7: xorl %ecx, %ecx
  55. movl %esp, %ebx
  56. movl %ecx, %edx
  57. movl $__NR_gettimeofday, %eax
  58. ENTER_KERNEL
  59. /* Compute relative timeout. */
  60. movl 4(%esp), %eax
  61. movl $1000, %edx
  62. mul %edx /* Milli seconds to nano seconds. */
  63. movl (%edi), %ecx
  64. movl 4(%edi), %edx
  65. subl (%esp), %ecx
  66. subl %eax, %edx
  67. jns 5f
  68. addl $1000000000, %edx
  69. subl $1, %ecx
  70. 5: testl %ecx, %ecx
  71. movl $ETIMEDOUT, %esi
  72. js 6f /* Time is already up. */
  73. movl %ecx, (%esp) /* Store relative timeout. */
  74. movl %edx, 4(%esp)
  75. .LcleanupSTART:
  76. call __pthread_enable_asynccancel
  77. movl %eax, 8(%esp)
  78. movl 28(%esp), %ebx /* Load semaphore address. */
  79. #if FUTEX_WAIT == 0
  80. movl PRIVATE(%ebx), %ecx
  81. #else
  82. movl $FUTEX_WAIT, %ecx
  83. orl PRIVATE(%ebx), %ecx
  84. #endif
  85. movl %esp, %esi
  86. xorl %edx, %edx
  87. movl $SYS_futex, %eax
  88. ENTER_KERNEL
  89. movl %eax, %esi
  90. movl 8(%esp), %eax
  91. call __pthread_disable_asynccancel
  92. .LcleanupEND:
  93. testl %esi, %esi
  94. je 9f
  95. cmpl $-EWOULDBLOCK, %esi
  96. jne 3f
  97. 9: movl (%ebx), %eax
  98. 8: testl %eax, %eax
  99. je 7b
  100. leal -1(%eax), %ecx
  101. LOCK
  102. cmpxchgl %ecx, (%ebx)
  103. jne 8b
  104. xorl %eax, %eax
  105. LOCK
  106. decl NWAITERS(%ebx)
  107. 10: addl $12, %esp
  108. .Ladd_esp:
  109. popl %ebx
  110. .Lpop_ebx:
  111. popl %edi
  112. .Lpop_edi:
  113. popl %esi
  114. .Lpop_esi:
  115. ret
  116. .Lafter_ret:
  117. 3: negl %esi
  118. 6:
  119. #ifdef __PIC__
  120. call __x86.get_pc_thunk.bx
  121. #else
  122. movl $4f, %ebx
  123. 4:
  124. #endif
  125. addl $_GLOBAL_OFFSET_TABLE_, %ebx
  126. #if USE___THREAD
  127. # ifdef NO_TLS_DIRECT_SEG_REFS
  128. movl errno@gotntpoff(%ebx), %edx
  129. addl %gs:0, %edx
  130. movl %esi, (%edx)
  131. # else
  132. movl errno@gotntpoff(%ebx), %edx
  133. movl %esi, %gs:(%edx)
  134. # endif
  135. #else
  136. call __errno_location@plt
  137. movl %esi, (%eax)
  138. #endif
  139. movl 28(%esp), %ebx /* Load semaphore address. */
  140. orl $-1, %eax
  141. jmp 10b
  142. .size sem_timedwait,.-sem_timedwait
  143. .type sem_wait_cleanup,@function
  144. sem_wait_cleanup:
  145. LOCK
  146. decl NWAITERS(%ebx)
  147. movl %eax, (%esp)
  148. .LcallUR:
  149. call _Unwind_Resume@PLT
  150. hlt
  151. .LENDCODE:
  152. .size sem_wait_cleanup,.-sem_wait_cleanup
  153. .section .gcc_except_table,"a",@progbits
  154. .LexceptSTART:
  155. .byte 0xff # @LPStart format (omit)
  156. .byte 0xff # @TType format (omit)
  157. .byte 0x01 # call-site format
  158. # DW_EH_PE_uleb128
  159. .uleb128 .Lcstend-.Lcstbegin
  160. .Lcstbegin:
  161. .uleb128 .LcleanupSTART-.LSTARTCODE
  162. .uleb128 .LcleanupEND-.LcleanupSTART
  163. .uleb128 sem_wait_cleanup-.LSTARTCODE
  164. .uleb128 0
  165. .uleb128 .LcallUR-.LSTARTCODE
  166. .uleb128 .LENDCODE-.LcallUR
  167. .uleb128 0
  168. .uleb128 0
  169. .Lcstend:
  170. .section .eh_frame,"a",@progbits
  171. .LSTARTFRAME:
  172. .long .LENDCIE-.LSTARTCIE # Length of the CIE.
  173. .LSTARTCIE:
  174. .long 0 # CIE ID.
  175. .byte 1 # Version number.
  176. #ifdef SHARED
  177. .string "zPLR" # NUL-terminated augmentation
  178. # string.
  179. #else
  180. .string "zPL" # NUL-terminated augmentation
  181. # string.
  182. #endif
  183. .uleb128 1 # Code alignment factor.
  184. .sleb128 -4 # Data alignment factor.
  185. .byte 8 # Return address register
  186. # column.
  187. #ifdef SHARED
  188. .uleb128 7 # Augmentation value length.
  189. .byte 0x9b # Personality: DW_EH_PE_pcrel
  190. # + DW_EH_PE_sdata4
  191. # + DW_EH_PE_indirect
  192. .long DW.ref.__gcc_personality_v0-.
  193. .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel
  194. # + DW_EH_PE_sdata4.
  195. .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel
  196. # + DW_EH_PE_sdata4.
  197. #else
  198. .uleb128 6 # Augmentation value length.
  199. .byte 0x0 # Personality: absolute
  200. .long __gcc_personality_v0
  201. .byte 0x0 # LSDA Encoding: absolute
  202. #endif
  203. .byte 0x0c # DW_CFA_def_cfa
  204. .uleb128 4
  205. .uleb128 4
  206. .byte 0x88 # DW_CFA_offset, column 0x10
  207. .uleb128 1
  208. .align 4
  209. .LENDCIE:
  210. .long .LENDFDE-.LSTARTFDE # Length of the FDE.
  211. .LSTARTFDE:
  212. .long .LSTARTFDE-.LSTARTFRAME # CIE pointer.
  213. #ifdef SHARED
  214. .long .LSTARTCODE-. # PC-relative start address
  215. # of the code.
  216. #else
  217. .long .LSTARTCODE # Start address of the code.
  218. #endif
  219. .long .LENDCODE-.LSTARTCODE # Length of the code.
  220. .uleb128 4 # Augmentation size
  221. #ifdef SHARED
  222. .long .LexceptSTART-.
  223. #else
  224. .long .LexceptSTART
  225. #endif
  226. .byte 4 # DW_CFA_advance_loc4
  227. .long .Lpush_esi-.LSTARTCODE
  228. .byte 14 # DW_CFA_def_cfa_offset
  229. .uleb128 8
  230. .byte 0x86 # DW_CFA_offset %esi
  231. .uleb128 2
  232. .byte 4 # DW_CFA_advance_loc4
  233. .long .Lpush_edi-.Lpush_esi
  234. .byte 14 # DW_CFA_def_cfa_offset
  235. .uleb128 12
  236. .byte 0x87 # DW_CFA_offset %edi
  237. .uleb128 3
  238. .byte 4 # DW_CFA_advance_loc4
  239. .long .Lpush_ebx-.Lpush_edi
  240. .byte 14 # DW_CFA_def_cfa_offset
  241. .uleb128 16
  242. .byte 0x83 # DW_CFA_offset %ebx
  243. .uleb128 4
  244. .byte 4 # DW_CFA_advance_loc4
  245. .long .Lsub_esp-.Lpush_ebx
  246. .byte 14 # DW_CFA_def_cfa_offset
  247. .uleb128 28
  248. .byte 4 # DW_CFA_advance_loc4
  249. .long .Ladd_esp-.Lsub_esp
  250. .byte 14 # DW_CFA_def_cfa_offset
  251. .uleb128 16
  252. .byte 4 # DW_CFA_advance_loc4
  253. .long .Lpop_ebx-.Ladd_esp
  254. .byte 14 # DW_CFA_def_cfa_offset
  255. .uleb128 12
  256. .byte 0xc3 # DW_CFA_restore %ebx
  257. .byte 4 # DW_CFA_advance_loc4
  258. .long .Lpop_edi-.Lpop_ebx
  259. .byte 14 # DW_CFA_def_cfa_offset
  260. .uleb128 8
  261. .byte 0xc7 # DW_CFA_restore %edi
  262. .byte 4 # DW_CFA_advance_loc4
  263. .long .Lpop_esi-.Lpop_edi
  264. .byte 14 # DW_CFA_def_cfa_offset
  265. .uleb128 4
  266. .byte 0xc6 # DW_CFA_restore %esi
  267. .byte 4 # DW_CFA_advance_loc4
  268. .long .Lafter_ret-.Lpop_esi
  269. .byte 14 # DW_CFA_def_cfa_offset
  270. .uleb128 28
  271. .byte 0x86 # DW_CFA_offset %esi
  272. .uleb128 2
  273. .byte 0x87 # DW_CFA_offset %edi
  274. .uleb128 3
  275. .byte 0x83 # DW_CFA_offset %ebx
  276. .uleb128 4
  277. .align 4
  278. .LENDFDE:
  279. #ifdef SHARED
  280. .hidden DW.ref.__gcc_personality_v0
  281. .weak DW.ref.__gcc_personality_v0
  282. .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
  283. .align 4
  284. .type DW.ref.__gcc_personality_v0, @object
  285. .size DW.ref.__gcc_personality_v0, 4
  286. DW.ref.__gcc_personality_v0:
  287. .long __gcc_personality_v0
  288. #endif