sem_timedwait.S 7.1 KB

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