pthread_cond_timedwait.S 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. /* Copyright (C) 2002-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 <lowlevellock.h>
  17. #include <lowlevelcond.h>
  18. #include <pthread-pi-defines.h>
  19. #include <pthread-errnos.h>
  20. #include <bits/kernel-features.h>
  21. #include <tcb-offsets.h>
  22. /* For the calculation see asm/vsyscall.h. */
  23. #define VSYSCALL_ADDR_vgettimeofday 0xffffffffff600000
  24. .text
  25. /* int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex,
  26. const struct timespec *abstime) */
  27. .globl __pthread_cond_timedwait
  28. .type __pthread_cond_timedwait, @function
  29. .protected __pthread_cond_timedwait
  30. .align 16
  31. __pthread_cond_timedwait:
  32. .LSTARTCODE:
  33. cfi_startproc
  34. pushq %r12
  35. cfi_adjust_cfa_offset(8)
  36. cfi_rel_offset(%r12, 0)
  37. pushq %r13
  38. cfi_adjust_cfa_offset(8)
  39. cfi_rel_offset(%r13, 0)
  40. pushq %r14
  41. cfi_adjust_cfa_offset(8)
  42. cfi_rel_offset(%r14, 0)
  43. pushq %r15
  44. cfi_adjust_cfa_offset(8)
  45. cfi_rel_offset(%r15, 0)
  46. #ifdef __ASSUME_FUTEX_CLOCK_REALTIME
  47. # define FRAME_SIZE 32
  48. #else
  49. # define FRAME_SIZE 48
  50. #endif
  51. subq $FRAME_SIZE, %rsp
  52. cfi_adjust_cfa_offset(FRAME_SIZE)
  53. cfi_remember_state
  54. cmpq $1000000000, 8(%rdx)
  55. movl $EINVAL, %eax
  56. jae 48f
  57. /* Stack frame:
  58. rsp + 48
  59. +--------------------------+
  60. rsp + 32 | timeout value |
  61. +--------------------------+
  62. rsp + 24 | old wake_seq value |
  63. +--------------------------+
  64. rsp + 16 | mutex pointer |
  65. +--------------------------+
  66. rsp + 8 | condvar pointer |
  67. +--------------------------+
  68. rsp + 4 | old broadcast_seq value |
  69. +--------------------------+
  70. rsp + 0 | old cancellation mode |
  71. +--------------------------+
  72. */
  73. cmpq $-1, dep_mutex(%rdi)
  74. /* Prepare structure passed to cancellation handler. */
  75. movq %rdi, 8(%rsp)
  76. movq %rsi, 16(%rsp)
  77. movq %rdx, %r13
  78. je 22f
  79. movq %rsi, dep_mutex(%rdi)
  80. 22:
  81. #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
  82. # ifdef __PIC__
  83. cmpl $0, __have_futex_clock_realtime@GOTOFF(%rip)
  84. # else
  85. cmpl $0, __have_futex_clock_realtime
  86. # endif
  87. je .Lreltmo
  88. #endif
  89. /* Get internal lock. */
  90. movl $1, %esi
  91. xorl %eax, %eax
  92. LOCK
  93. #if cond_lock == 0
  94. cmpxchgl %esi, (%rdi)
  95. #else
  96. cmpxchgl %esi, cond_lock(%rdi)
  97. #endif
  98. jnz 31f
  99. /* Unlock the mutex. */
  100. 32: movq 16(%rsp), %rdi
  101. xorl %esi, %esi
  102. callq __pthread_mutex_unlock_usercnt
  103. testl %eax, %eax
  104. jne 46f
  105. movq 8(%rsp), %rdi
  106. incq total_seq(%rdi)
  107. incl cond_futex(%rdi)
  108. addl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
  109. /* Get and store current wakeup_seq value. */
  110. movq 8(%rsp), %rdi
  111. movq wakeup_seq(%rdi), %r9
  112. movl broadcast_seq(%rdi), %edx
  113. movq %r9, 24(%rsp)
  114. movl %edx, 4(%rsp)
  115. 38: movl cond_futex(%rdi), %r12d
  116. /* Unlock. */
  117. LOCK
  118. #if cond_lock == 0
  119. decl (%rdi)
  120. #else
  121. decl cond_lock(%rdi)
  122. #endif
  123. jne 33f
  124. .LcleanupSTART1:
  125. 34: callq __pthread_enable_asynccancel
  126. movl %eax, (%rsp)
  127. movq %r13, %r10
  128. movl $FUTEX_WAIT_BITSET, %esi
  129. cmpq $-1, dep_mutex(%rdi)
  130. je 60f
  131. movq dep_mutex(%rdi), %r8
  132. /* Requeue to a non-robust PI mutex if the PI bit is set and
  133. the robust bit is not set. */
  134. movl MUTEX_KIND(%r8), %eax
  135. andl $(ROBUST_BIT|PI_BIT), %eax
  136. cmpl $PI_BIT, %eax
  137. jne 61f
  138. movl $(FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %esi
  139. xorl %eax, %eax
  140. /* The following only works like this because we only support
  141. two clocks, represented using a single bit. */
  142. testl $1, cond_nwaiters(%rdi)
  143. movl $FUTEX_CLOCK_REALTIME, %edx
  144. cmove %edx, %eax
  145. orl %eax, %esi
  146. movq %r12, %rdx
  147. addq $cond_futex, %rdi
  148. movl $SYS_futex, %eax
  149. syscall
  150. movl $1, %r15d
  151. #ifdef __ASSUME_REQUEUE_PI
  152. jmp 62f
  153. #else
  154. cmpq $-4095, %rax
  155. jnae 62f
  156. subq $cond_futex, %rdi
  157. #endif
  158. 61: movl $(FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG), %esi
  159. 60: xorl %r15d, %r15d
  160. xorl %eax, %eax
  161. /* The following only works like this because we only support
  162. two clocks, represented using a single bit. */
  163. testl $1, cond_nwaiters(%rdi)
  164. movl $FUTEX_CLOCK_REALTIME, %edx
  165. movl $0xffffffff, %r9d
  166. cmove %edx, %eax
  167. orl %eax, %esi
  168. movq %r12, %rdx
  169. addq $cond_futex, %rdi
  170. movl $SYS_futex, %eax
  171. syscall
  172. 62: movq %rax, %r14
  173. movl (%rsp), %edi
  174. callq __pthread_disable_asynccancel
  175. .LcleanupEND1:
  176. /* Lock. */
  177. movq 8(%rsp), %rdi
  178. movl $1, %esi
  179. xorl %eax, %eax
  180. LOCK
  181. #if cond_lock == 0
  182. cmpxchgl %esi, (%rdi)
  183. #else
  184. cmpxchgl %esi, cond_lock(%rdi)
  185. #endif
  186. jne 35f
  187. 36: movl broadcast_seq(%rdi), %edx
  188. movq woken_seq(%rdi), %rax
  189. movq wakeup_seq(%rdi), %r9
  190. cmpl 4(%rsp), %edx
  191. jne 53f
  192. cmpq 24(%rsp), %r9
  193. jbe 45f
  194. cmpq %rax, %r9
  195. ja 39f
  196. 45: cmpq $-ETIMEDOUT, %r14
  197. jne 38b
  198. 99: incq wakeup_seq(%rdi)
  199. incl cond_futex(%rdi)
  200. movl $ETIMEDOUT, %r14d
  201. jmp 44f
  202. 53: xorq %r14, %r14
  203. jmp 54f
  204. 39: xorq %r14, %r14
  205. 44: incq woken_seq(%rdi)
  206. 54: subl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
  207. /* Wake up a thread which wants to destroy the condvar object. */
  208. cmpq $0xffffffffffffffff, total_seq(%rdi)
  209. jne 55f
  210. movl cond_nwaiters(%rdi), %eax
  211. andl $~((1 << nwaiters_shift) - 1), %eax
  212. jne 55f
  213. addq $cond_nwaiters, %rdi
  214. cmpq $-1, dep_mutex-cond_nwaiters(%rdi)
  215. movl $1, %edx
  216. #ifdef __ASSUME_PRIVATE_FUTEX
  217. movl $FUTEX_WAKE, %eax
  218. movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
  219. cmove %eax, %esi
  220. #else
  221. movl $0, %eax
  222. movl %fs:PRIVATE_FUTEX, %esi
  223. cmove %eax, %esi
  224. orl $FUTEX_WAKE, %esi
  225. #endif
  226. movl $SYS_futex, %eax
  227. syscall
  228. subq $cond_nwaiters, %rdi
  229. 55: LOCK
  230. #if cond_lock == 0
  231. decl (%rdi)
  232. #else
  233. decl cond_lock(%rdi)
  234. #endif
  235. jne 40f
  236. /* If requeue_pi is used the kernel performs the locking of the
  237. mutex. */
  238. 41: movq 16(%rsp), %rdi
  239. testl %r15d, %r15d
  240. jnz 64f
  241. callq __pthread_mutex_cond_lock
  242. 63: testq %rax, %rax
  243. cmoveq %r14, %rax
  244. 48: addq $FRAME_SIZE, %rsp
  245. cfi_adjust_cfa_offset(-FRAME_SIZE)
  246. popq %r15
  247. cfi_adjust_cfa_offset(-8)
  248. cfi_restore(%r15)
  249. popq %r14
  250. cfi_adjust_cfa_offset(-8)
  251. cfi_restore(%r14)
  252. popq %r13
  253. cfi_adjust_cfa_offset(-8)
  254. cfi_restore(%r13)
  255. popq %r12
  256. cfi_adjust_cfa_offset(-8)
  257. cfi_restore(%r12)
  258. retq
  259. cfi_restore_state
  260. 64: callq __pthread_mutex_cond_lock_adjust
  261. movq %r14, %rax
  262. jmp 48b
  263. /* Initial locking failed. */
  264. 31:
  265. #if cond_lock != 0
  266. addq $cond_lock, %rdi
  267. #endif
  268. cmpq $-1, dep_mutex-cond_lock(%rdi)
  269. movl $LLL_PRIVATE, %eax
  270. movl $LLL_SHARED, %esi
  271. cmovne %eax, %esi
  272. callq __lll_lock_wait
  273. jmp 32b
  274. /* Unlock in loop requires wakeup. */
  275. 33:
  276. #if cond_lock != 0
  277. addq $cond_lock, %rdi
  278. #endif
  279. cmpq $-1, dep_mutex-cond_lock(%rdi)
  280. movl $LLL_PRIVATE, %eax
  281. movl $LLL_SHARED, %esi
  282. cmovne %eax, %esi
  283. callq __lll_unlock_wake
  284. jmp 34b
  285. /* Locking in loop failed. */
  286. 35:
  287. #if cond_lock != 0
  288. addq $cond_lock, %rdi
  289. #endif
  290. cmpq $-1, dep_mutex-cond_lock(%rdi)
  291. movl $LLL_PRIVATE, %eax
  292. movl $LLL_SHARED, %esi
  293. cmovne %eax, %esi
  294. callq __lll_lock_wait
  295. #if cond_lock != 0
  296. subq $cond_lock, %rdi
  297. #endif
  298. jmp 36b
  299. /* Unlock after loop requires wakeup. */
  300. 40:
  301. #if cond_lock != 0
  302. addq $cond_lock, %rdi
  303. #endif
  304. cmpq $-1, dep_mutex-cond_lock(%rdi)
  305. movl $LLL_PRIVATE, %eax
  306. movl $LLL_SHARED, %esi
  307. cmovne %eax, %esi
  308. callq __lll_unlock_wake
  309. jmp 41b
  310. /* The initial unlocking of the mutex failed. */
  311. 46: movq 8(%rsp), %rdi
  312. movq %rax, (%rsp)
  313. LOCK
  314. #if cond_lock == 0
  315. decl (%rdi)
  316. #else
  317. decl cond_lock(%rdi)
  318. #endif
  319. jne 47f
  320. #if cond_lock != 0
  321. addq $cond_lock, %rdi
  322. #endif
  323. cmpq $-1, dep_mutex-cond_lock(%rdi)
  324. movl $LLL_PRIVATE, %eax
  325. movl $LLL_SHARED, %esi
  326. cmovne %eax, %esi
  327. callq __lll_unlock_wake
  328. 47: movq (%rsp), %rax
  329. jmp 48b
  330. #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
  331. .Lreltmo:
  332. xorl %r15d, %r15d
  333. /* Get internal lock. */
  334. movl $1, %esi
  335. xorl %eax, %eax
  336. LOCK
  337. # if cond_lock == 0
  338. cmpxchgl %esi, (%rdi)
  339. # else
  340. cmpxchgl %esi, cond_lock(%rdi)
  341. # endif
  342. jnz 1f
  343. /* Unlock the mutex. */
  344. 2: movq 16(%rsp), %rdi
  345. xorl %esi, %esi
  346. callq __pthread_mutex_unlock_usercnt
  347. testl %eax, %eax
  348. jne 46b
  349. movq 8(%rsp), %rdi
  350. incq total_seq(%rdi)
  351. incl cond_futex(%rdi)
  352. addl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
  353. /* Get and store current wakeup_seq value. */
  354. movq 8(%rsp), %rdi
  355. movq wakeup_seq(%rdi), %r9
  356. movl broadcast_seq(%rdi), %edx
  357. movq %r9, 24(%rsp)
  358. movl %edx, 4(%rsp)
  359. /* Get the current time. */
  360. 8:
  361. # ifdef __NR_clock_gettime
  362. /* Get the clock number. Note that the field in the condvar
  363. structure stores the number minus 1. */
  364. movq 8(%rsp), %rdi
  365. movl cond_nwaiters(%rdi), %edi
  366. andl $((1 << nwaiters_shift) - 1), %edi
  367. /* Only clocks 0 and 1 are allowed so far. Both are handled in the
  368. kernel. */
  369. leaq 32(%rsp), %rsi
  370. 26: movl $__NR_clock_gettime, %eax
  371. syscall
  372. 27:
  373. # ifndef __ASSUME_POSIX_TIMERS
  374. cmpq $-ENOSYS, %rax
  375. je 19f
  376. # endif
  377. /* Compute relative timeout. */
  378. movq (%r13), %rcx
  379. movq 8(%r13), %rdx
  380. subq 32(%rsp), %rcx
  381. subq 40(%rsp), %rdx
  382. # else
  383. leaq 24(%rsp), %rdi
  384. xorl %esi, %esi
  385. movq $VSYSCALL_ADDR_vgettimeofday, %rax
  386. callq *%rax
  387. /* Compute relative timeout. */
  388. movq 40(%rsp), %rax
  389. movl $1000, %edx
  390. mul %rdx /* Milli seconds to nano seconds. */
  391. movq (%r13), %rcx
  392. movq 8(%r13), %rdx
  393. subq 32(%rsp), %rcx
  394. subq %rax, %rdx
  395. # endif
  396. jns 12f
  397. addq $1000000000, %rdx
  398. decq %rcx
  399. 12: testq %rcx, %rcx
  400. movq 8(%rsp), %rdi
  401. movq $-ETIMEDOUT, %r14
  402. js 6f
  403. /* Store relative timeout. */
  404. 21: movq %rcx, 32(%rsp)
  405. movq %rdx, 40(%rsp)
  406. movl cond_futex(%rdi), %r12d
  407. /* Unlock. */
  408. LOCK
  409. # if cond_lock == 0
  410. decl (%rdi)
  411. # else
  412. decl cond_lock(%rdi)
  413. # endif
  414. jne 3f
  415. .LcleanupSTART2:
  416. 4: callq __pthread_enable_asynccancel
  417. movl %eax, (%rsp)
  418. leaq 32(%rsp), %r10
  419. cmpq $-1, dep_mutex(%rdi)
  420. movq %r12, %rdx
  421. # ifdef __ASSUME_PRIVATE_FUTEX
  422. movl $FUTEX_WAIT, %eax
  423. movl $(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), %esi
  424. cmove %eax, %esi
  425. # else
  426. movl $0, %eax
  427. movl %fs:PRIVATE_FUTEX, %esi
  428. cmove %eax, %esi
  429. # if FUTEX_WAIT != 0
  430. orl $FUTEX_WAIT, %esi
  431. # endif
  432. # endif
  433. addq $cond_futex, %rdi
  434. movl $SYS_futex, %eax
  435. syscall
  436. movq %rax, %r14
  437. movl (%rsp), %edi
  438. callq __pthread_disable_asynccancel
  439. .LcleanupEND2:
  440. /* Lock. */
  441. movq 8(%rsp), %rdi
  442. movl $1, %esi
  443. xorl %eax, %eax
  444. LOCK
  445. # if cond_lock == 0
  446. cmpxchgl %esi, (%rdi)
  447. # else
  448. cmpxchgl %esi, cond_lock(%rdi)
  449. # endif
  450. jne 5f
  451. 6: movl broadcast_seq(%rdi), %edx
  452. movq woken_seq(%rdi), %rax
  453. movq wakeup_seq(%rdi), %r9
  454. cmpl 4(%rsp), %edx
  455. jne 53b
  456. cmpq 24(%rsp), %r9
  457. jbe 15f
  458. cmpq %rax, %r9
  459. ja 39b
  460. 15: cmpq $-ETIMEDOUT, %r14
  461. jne 8b
  462. jmp 99b
  463. /* Initial locking failed. */
  464. 1:
  465. # if cond_lock != 0
  466. addq $cond_lock, %rdi
  467. # endif
  468. cmpq $-1, dep_mutex-cond_lock(%rdi)
  469. movl $LLL_PRIVATE, %eax
  470. movl $LLL_SHARED, %esi
  471. cmovne %eax, %esi
  472. callq __lll_lock_wait
  473. jmp 2b
  474. /* Unlock in loop requires wakeup. */
  475. 3:
  476. # if cond_lock != 0
  477. addq $cond_lock, %rdi
  478. # endif
  479. cmpq $-1, dep_mutex-cond_lock(%rdi)
  480. movl $LLL_PRIVATE, %eax
  481. movl $LLL_SHARED, %esi
  482. cmovne %eax, %esi
  483. callq __lll_unlock_wake
  484. jmp 4b
  485. /* Locking in loop failed. */
  486. 5:
  487. # if cond_lock != 0
  488. addq $cond_lock, %rdi
  489. # endif
  490. cmpq $-1, dep_mutex-cond_lock(%rdi)
  491. movl $LLL_PRIVATE, %eax
  492. movl $LLL_SHARED, %esi
  493. cmovne %eax, %esi
  494. callq __lll_lock_wait
  495. # if cond_lock != 0
  496. subq $cond_lock, %rdi
  497. # endif
  498. jmp 6b
  499. # if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
  500. /* clock_gettime not available. */
  501. 19: leaq 32(%rsp), %rdi
  502. xorl %esi, %esi
  503. movq $VSYSCALL_ADDR_vgettimeofday, %rax
  504. callq *%rax
  505. /* Compute relative timeout. */
  506. movq 40(%rsp), %rax
  507. movl $1000, %edx
  508. mul %rdx /* Milli seconds to nano seconds. */
  509. movq (%r13), %rcx
  510. movq 8(%r13), %rdx
  511. subq 32(%rsp), %rcx
  512. subq %rax, %rdx
  513. jns 20f
  514. addq $1000000000, %rdx
  515. decq %rcx
  516. 20: testq %rcx, %rcx
  517. movq 8(%rsp), %rdi
  518. movq $-ETIMEDOUT, %r14
  519. js 6b
  520. jmp 21b
  521. # endif
  522. #endif
  523. .size __pthread_cond_timedwait, .-__pthread_cond_timedwait
  524. weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait)
  525. .align 16
  526. .type __condvar_cleanup2, @function
  527. __condvar_cleanup2:
  528. /* Stack frame:
  529. rsp + 72
  530. +--------------------------+
  531. rsp + 64 | %r12 |
  532. +--------------------------+
  533. rsp + 56 | %r13 |
  534. +--------------------------+
  535. rsp + 48 | %r14 |
  536. +--------------------------+
  537. rsp + 24 | unused |
  538. +--------------------------+
  539. rsp + 16 | mutex pointer |
  540. +--------------------------+
  541. rsp + 8 | condvar pointer |
  542. +--------------------------+
  543. rsp + 4 | old broadcast_seq value |
  544. +--------------------------+
  545. rsp + 0 | old cancellation mode |
  546. +--------------------------+
  547. */
  548. movq %rax, 24(%rsp)
  549. /* Get internal lock. */
  550. movq 8(%rsp), %rdi
  551. movl $1, %esi
  552. xorl %eax, %eax
  553. LOCK
  554. #if cond_lock == 0
  555. cmpxchgl %esi, (%rdi)
  556. #else
  557. cmpxchgl %esi, cond_lock(%rdi)
  558. #endif
  559. jz 1f
  560. #if cond_lock != 0
  561. addq $cond_lock, %rdi
  562. #endif
  563. cmpq $-1, dep_mutex-cond_lock(%rdi)
  564. movl $LLL_PRIVATE, %eax
  565. movl $LLL_SHARED, %esi
  566. cmovne %eax, %esi
  567. callq __lll_lock_wait
  568. #if cond_lock != 0
  569. subq $cond_lock, %rdi
  570. #endif
  571. 1: movl broadcast_seq(%rdi), %edx
  572. cmpl 4(%rsp), %edx
  573. jne 3f
  574. /* We increment the wakeup_seq counter only if it is lower than
  575. total_seq. If this is not the case the thread was woken and
  576. then canceled. In this case we ignore the signal. */
  577. movq total_seq(%rdi), %rax
  578. cmpq wakeup_seq(%rdi), %rax
  579. jbe 6f
  580. incq wakeup_seq(%rdi)
  581. incl cond_futex(%rdi)
  582. 6: incq woken_seq(%rdi)
  583. 3: subl $(1 << nwaiters_shift), cond_nwaiters(%rdi)
  584. /* Wake up a thread which wants to destroy the condvar object. */
  585. xorq %r12, %r12
  586. cmpq $0xffffffffffffffff, total_seq(%rdi)
  587. jne 4f
  588. movl cond_nwaiters(%rdi), %eax
  589. andl $~((1 << nwaiters_shift) - 1), %eax
  590. jne 4f
  591. cmpq $-1, dep_mutex(%rdi)
  592. leaq cond_nwaiters(%rdi), %rdi
  593. movl $1, %edx
  594. #ifdef __ASSUME_PRIVATE_FUTEX
  595. movl $FUTEX_WAKE, %eax
  596. movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
  597. cmove %eax, %esi
  598. #else
  599. movl $0, %eax
  600. movl %fs:PRIVATE_FUTEX, %esi
  601. cmove %eax, %esi
  602. orl $FUTEX_WAKE, %esi
  603. #endif
  604. movl $SYS_futex, %eax
  605. syscall
  606. subq $cond_nwaiters, %rdi
  607. movl $1, %r12d
  608. 4: LOCK
  609. #if cond_lock == 0
  610. decl (%rdi)
  611. #else
  612. decl cond_lock(%rdi)
  613. #endif
  614. je 2f
  615. #if cond_lock != 0
  616. addq $cond_lock, %rdi
  617. #endif
  618. cmpq $-1, dep_mutex-cond_lock(%rdi)
  619. movl $LLL_PRIVATE, %eax
  620. movl $LLL_SHARED, %esi
  621. cmovne %eax, %esi
  622. callq __lll_unlock_wake
  623. /* Wake up all waiters to make sure no signal gets lost. */
  624. 2: testq %r12, %r12
  625. jnz 5f
  626. addq $cond_futex, %rdi
  627. cmpq $-1, dep_mutex-cond_futex(%rdi)
  628. movl $0x7fffffff, %edx
  629. #ifdef __ASSUME_PRIVATE_FUTEX
  630. movl $FUTEX_WAKE, %eax
  631. movl $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
  632. cmove %eax, %esi
  633. #else
  634. movl $0, %eax
  635. movl %fs:PRIVATE_FUTEX, %esi
  636. cmove %eax, %esi
  637. orl $FUTEX_WAKE, %esi
  638. #endif
  639. movl $SYS_futex, %eax
  640. syscall
  641. 5: movq 16(%rsp), %rdi
  642. callq __pthread_mutex_cond_lock
  643. movq 24(%rsp), %rdi
  644. movq FRAME_SIZE(%rsp), %r15
  645. movq FRAME_SIZE+8(%rsp), %r14
  646. movq FRAME_SIZE+16(%rsp), %r13
  647. movq FRAME_SIZE+24(%rsp), %r12
  648. .LcallUR:
  649. call _Unwind_Resume@PLT
  650. hlt
  651. .LENDCODE:
  652. cfi_endproc
  653. .size __condvar_cleanup2, .-__condvar_cleanup2
  654. .section .gcc_except_table,"a",@progbits
  655. .LexceptSTART:
  656. .byte DW_EH_PE_omit # @LPStart format
  657. .byte DW_EH_PE_omit # @TType format
  658. .byte DW_EH_PE_uleb128 # call-site format
  659. .uleb128 .Lcstend-.Lcstbegin
  660. .Lcstbegin:
  661. .uleb128 .LcleanupSTART1-.LSTARTCODE
  662. .uleb128 .LcleanupEND1-.LcleanupSTART1
  663. .uleb128 __condvar_cleanup2-.LSTARTCODE
  664. .uleb128 0
  665. #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
  666. .uleb128 .LcleanupSTART2-.LSTARTCODE
  667. .uleb128 .LcleanupEND2-.LcleanupSTART2
  668. .uleb128 __condvar_cleanup2-.LSTARTCODE
  669. .uleb128 0
  670. #endif
  671. .uleb128 .LcallUR-.LSTARTCODE
  672. .uleb128 .LENDCODE-.LcallUR
  673. .uleb128 0
  674. .uleb128 0
  675. .Lcstend:
  676. #ifdef SHARED
  677. .hidden DW.ref.__gcc_personality_v0
  678. .weak DW.ref.__gcc_personality_v0
  679. .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits
  680. .align 8
  681. .type DW.ref.__gcc_personality_v0, @object
  682. .size DW.ref.__gcc_personality_v0, 8
  683. DW.ref.__gcc_personality_v0:
  684. .quad __gcc_personality_v0
  685. #endif