pthread_cond_signal.S 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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 <lowlevellock.h>
  18. #include <lowlevelcond.h>
  19. #include <bits/kernel-features.h>
  20. #include <pthread-pi-defines.h>
  21. #include <pthread-errnos.h>
  22. #include <tls.h>
  23. .text
  24. /* int pthread_cond_signal (pthread_cond_t *cond) */
  25. .globl __pthread_cond_signal
  26. .type __pthread_cond_signal, @function
  27. .protected __pthread_cond_signal
  28. .align 16
  29. __pthread_cond_signal:
  30. cfi_startproc
  31. pushl %ebx
  32. cfi_adjust_cfa_offset(4)
  33. cfi_rel_offset(%ebx, 0)
  34. pushl %edi
  35. cfi_adjust_cfa_offset(4)
  36. cfi_rel_offset(%edi, 0)
  37. cfi_remember_state
  38. movl 12(%esp), %edi
  39. /* Get internal lock. */
  40. movl $1, %edx
  41. xorl %eax, %eax
  42. LOCK
  43. #if cond_lock == 0
  44. cmpxchgl %edx, (%edi)
  45. #else
  46. cmpxchgl %edx, cond_lock(%edi)
  47. #endif
  48. jnz 1f
  49. 2: leal cond_futex(%edi), %ebx
  50. movl total_seq+4(%edi), %eax
  51. movl total_seq(%edi), %ecx
  52. cmpl wakeup_seq+4(%edi), %eax
  53. #if cond_lock != 0
  54. /* Must use leal to preserve the flags. */
  55. leal cond_lock(%edi), %edi
  56. #endif
  57. ja 3f
  58. jb 4f
  59. cmpl wakeup_seq-cond_futex(%ebx), %ecx
  60. jbe 4f
  61. /* Bump the wakeup number. */
  62. 3: addl $1, wakeup_seq-cond_futex(%ebx)
  63. adcl $0, wakeup_seq-cond_futex+4(%ebx)
  64. addl $1, (%ebx)
  65. /* Wake up one thread. */
  66. pushl %esi
  67. cfi_adjust_cfa_offset(4)
  68. cfi_rel_offset(%esi, 0)
  69. pushl %ebp
  70. cfi_adjust_cfa_offset(4)
  71. cfi_rel_offset(%ebp, 0)
  72. #if FUTEX_PRIVATE_FLAG > 255
  73. xorl %ecx, %ecx
  74. #endif
  75. cmpl $-1, dep_mutex-cond_futex(%ebx)
  76. sete %cl
  77. je 8f
  78. movl dep_mutex-cond_futex(%ebx), %edx
  79. /* Requeue to a non-robust PI mutex if the PI bit is set and
  80. the robust bit is not set. */
  81. movl MUTEX_KIND(%edx), %eax
  82. andl $(ROBUST_BIT|PI_BIT), %eax
  83. cmpl $PI_BIT, %eax
  84. je 9f
  85. 8: subl $1, %ecx
  86. #ifdef __ASSUME_PRIVATE_FUTEX
  87. andl $FUTEX_PRIVATE_FLAG, %ecx
  88. #else
  89. andl %gs:PRIVATE_FUTEX, %ecx
  90. #endif
  91. addl $FUTEX_WAKE_OP, %ecx
  92. movl $SYS_futex, %eax
  93. movl $1, %edx
  94. movl $1, %esi
  95. movl $FUTEX_OP_CLEAR_WAKE_IF_GT_ONE, %ebp
  96. /* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for
  97. sysenter.
  98. ENTER_KERNEL */
  99. int $0x80
  100. popl %ebp
  101. cfi_adjust_cfa_offset(-4)
  102. cfi_restore(%ebp)
  103. popl %esi
  104. cfi_adjust_cfa_offset(-4)
  105. cfi_restore(%esi)
  106. /* For any kind of error, we try again with WAKE.
  107. The general test also covers running on old kernels. */
  108. cmpl $-4095, %eax
  109. jae 7f
  110. 6: xorl %eax, %eax
  111. popl %edi
  112. cfi_adjust_cfa_offset(-4)
  113. cfi_restore(%edi)
  114. popl %ebx
  115. cfi_adjust_cfa_offset(-4)
  116. cfi_restore(%ebx)
  117. ret
  118. cfi_restore_state
  119. 9: movl $(FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG), %ecx
  120. movl $SYS_futex, %eax
  121. movl $1, %edx
  122. xorl %esi, %esi
  123. movl dep_mutex-cond_futex(%ebx), %edi
  124. movl (%ebx), %ebp
  125. /* FIXME: Until Ingo fixes 4G/4G vDSO, 6 arg syscalls are broken for
  126. sysenter.
  127. ENTER_KERNEL */
  128. int $0x80
  129. popl %ebp
  130. popl %esi
  131. leal -cond_futex(%ebx), %edi
  132. /* For any kind of error, we try again with WAKE.
  133. The general test also covers running on old kernels. */
  134. cmpl $-4095, %eax
  135. jb 4f
  136. 7:
  137. #ifdef __ASSUME_PRIVATE_FUTEX
  138. andl $FUTEX_PRIVATE_FLAG, %ecx
  139. #else
  140. andl %gs:PRIVATE_FUTEX, %ecx
  141. #endif
  142. orl $FUTEX_WAKE, %ecx
  143. xorl $(FUTEX_WAKE ^ FUTEX_WAKE_OP), %ecx
  144. movl $SYS_futex, %eax
  145. /* %edx should be 1 already from $FUTEX_WAKE_OP syscall.
  146. movl $1, %edx */
  147. ENTER_KERNEL
  148. /* Unlock. Note that at this point %edi always points to
  149. cond_lock. */
  150. 4: LOCK
  151. subl $1, (%edi)
  152. je 6b
  153. /* Unlock in loop requires wakeup. */
  154. 5: movl %edi, %eax
  155. #if (LLL_SHARED-LLL_PRIVATE) > 255
  156. xorl %ecx, %ecx
  157. #endif
  158. cmpl $-1, dep_mutex-cond_futex(%ebx)
  159. setne %cl
  160. subl $1, %ecx
  161. andl $(LLL_SHARED-LLL_PRIVATE), %ecx
  162. #if LLL_PRIVATE != 0
  163. addl $LLL_PRIVATE, %ecx
  164. #endif
  165. call __lll_unlock_wake
  166. jmp 6b
  167. /* Initial locking failed. */
  168. 1:
  169. #if cond_lock == 0
  170. movl %edi, %edx
  171. #else
  172. leal cond_lock(%edi), %edx
  173. #endif
  174. #if (LLL_SHARED-LLL_PRIVATE) > 255
  175. xorl %ecx, %ecx
  176. #endif
  177. cmpl $-1, dep_mutex(%edi)
  178. setne %cl
  179. subl $1, %ecx
  180. andl $(LLL_SHARED-LLL_PRIVATE), %ecx
  181. #if LLL_PRIVATE != 0
  182. addl $LLL_PRIVATE, %ecx
  183. #endif
  184. call __lll_lock_wait
  185. jmp 2b
  186. cfi_endproc
  187. .size __pthread_cond_signal, .-__pthread_cond_signal
  188. weak_alias(__pthread_cond_signal, pthread_cond_signal)