cancellation.S 3.1 KB

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