cancellation.S 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* Copyright (C) 2009 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
  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 <tcb-offsets.h>
  17. #include <bits/kernel-features.h>
  18. #include "lowlevellock.h"
  19. #ifdef IS_IN_libpthread
  20. # ifdef SHARED
  21. # define __pthread_unwind __GI___pthread_unwind
  22. # endif
  23. #else
  24. # ifndef SHARED
  25. .weak __pthread_unwind
  26. # endif
  27. #endif
  28. #ifdef __ASSUME_PRIVATE_FUTEX
  29. # define LOAD_PRIVATE_FUTEX_WAIT(reg) \
  30. movl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
  31. #else
  32. # if FUTEX_WAIT == 0
  33. # define LOAD_PRIVATE_FUTEX_WAIT(reg) \
  34. movl %fs:PRIVATE_FUTEX, reg
  35. # else
  36. # define LOAD_PRIVATE_FUTEX_WAIT(reg) \
  37. movl %fs:PRIVATE_FUTEX, reg ; \
  38. orl $FUTEX_WAIT, reg
  39. # endif
  40. #endif
  41. /* It is crucial that the functions in this file don't modify registers
  42. other than %rax and %r11. The syscall wrapper code depends on this
  43. because it doesn't explicitly save the other registers which hold
  44. relevant values. */
  45. .text
  46. .hidden __pthread_enable_asynccancel
  47. ENTRY(__pthread_enable_asynccancel)
  48. movl %fs:CANCELHANDLING, %eax
  49. 2: movl %eax, %r11d
  50. orl $TCB_CANCELTYPE_BITMASK, %r11d
  51. cmpl %eax, %r11d
  52. je 1f
  53. lock
  54. cmpxchgl %r11d, %fs:CANCELHANDLING
  55. jnz 2b
  56. andl $(TCB_CANCELSTATE_BITMASK|TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK|TCB_EXITING_BITMASK|TCB_CANCEL_RESTMASK|TCB_TERMINATED_BITMASK), %r11d
  57. cmpl $(TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK), %r11d
  58. je 3f
  59. 1: ret
  60. 3: movq $TCB_PTHREAD_CANCELED, %fs:RESULT
  61. lock
  62. orl $TCB_EXITING_BITMASK, %fs:CANCELHANDLING
  63. movq %fs:CLEANUP_JMP_BUF, %rdi
  64. #ifdef SHARED
  65. call __pthread_unwind@PLT
  66. #else
  67. call __pthread_unwind
  68. #endif
  69. hlt
  70. END(__pthread_enable_asynccancel)
  71. .hidden __pthread_disable_asynccancel
  72. ENTRY(__pthread_disable_asynccancel)
  73. testl $TCB_CANCELTYPE_BITMASK, %edi
  74. jnz 1f
  75. movl %fs:CANCELHANDLING, %eax
  76. 2: movl %eax, %r11d
  77. andl $~TCB_CANCELTYPE_BITMASK, %r11d
  78. lock
  79. cmpxchgl %r11d, %fs:CANCELHANDLING
  80. jnz 2b
  81. movl %r11d, %eax
  82. 3: andl $(TCB_CANCELING_BITMASK|TCB_CANCELED_BITMASK), %eax
  83. cmpl $TCB_CANCELING_BITMASK, %eax
  84. je 4f
  85. 1: ret
  86. /* Performance doesn't matter in this loop. We will
  87. delay until the thread is canceled. And we will unlikely
  88. enter the loop twice. */
  89. 4: movq %fs:0, %rdi
  90. movl $__NR_futex, %eax
  91. xorq %r10, %r10
  92. addq $CANCELHANDLING, %rdi
  93. LOAD_PRIVATE_FUTEX_WAIT (%esi)
  94. syscall
  95. movl %fs:CANCELHANDLING, %eax
  96. jmp 3b
  97. END(__pthread_disable_asynccancel)