Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

237 lines
5.6 KiB

  1. TITLE "Fast Mutex Support"
  2. ;++
  3. ;
  4. ; Copyright (c) 1994 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; fmutex.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements teh code necessary to acquire and release fast
  13. ; mutexes without raising or lowering IRQL.
  14. ;
  15. ; Author:
  16. ;
  17. ; David N. Cutler (davec) 26-May-1994
  18. ;
  19. ; Environment:
  20. ;
  21. ; Kernel mode only.
  22. ;
  23. ; Revision History:
  24. ;
  25. ;--
  26. .386p
  27. .xlist
  28. include ks386.inc
  29. include callconv.inc ; calling convention macros
  30. include mac386.inc
  31. .list
  32. EXTRNP _KeSetEventBoostPriority, 2
  33. EXTRNP _KeWaitForSingleObject, 5
  34. if DBG
  35. EXTRNP _KeGetCurrentIrql,0,IMPORT
  36. EXTRNP ___KeGetCurrentThread,0
  37. EXTRNP _KeBugCheckEx,5
  38. endif
  39. ifdef NT_UP
  40. LOCK_ADD equ add
  41. LOCK_DEC equ dec
  42. else
  43. LOCK_ADD equ lock add
  44. LOCK_DEC equ lock dec
  45. endif
  46. _TEXT$00 SEGMENT DWORD PUBLIC 'CODE'
  47. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  48. ;++
  49. ;
  50. ; VOID
  51. ; FASTCALL
  52. ; ExAcquireFastMutexUnsafe (
  53. ; IN PFAST_MUTEX FastMutex
  54. ; )
  55. ;
  56. ; Routine description:
  57. ;
  58. ; This function acquires ownership of a fast mutex, but does not raise
  59. ; IRQL to APC level.
  60. ;
  61. ; Arguments:
  62. ;
  63. ; (ecx) = FastMutex - Supplies a pointer to a fast mutex.
  64. ;
  65. ; Return Value:
  66. ;
  67. ; None.
  68. ;
  69. ;--
  70. cPublicFastCall ExAcquireFastMutexUnsafe,1
  71. cPublicFpo 0,0
  72. if DBG
  73. push ecx
  74. stdCall _KeGetCurrentIrql
  75. pop ecx
  76. ;
  77. ; Caller must already be at APC_LEVEL or have APCs blocked.
  78. ;
  79. cmp al, APC_LEVEL
  80. mov eax,PCR[PcPrcbData+PbCurrentThread] ; grab the current thread 1st
  81. je short afm09 ; APCs disabled, this is ok
  82. cmp dword ptr [eax]+ThKernelApcDisable, 0
  83. jne short afm09 ; APCs disabled, this is ok
  84. cmp dword ptr [eax]+ThTeb, 0
  85. je short afm09 ; No TEB ==> system thread, this is ok
  86. test dword ptr [eax]+ThTeb, 080000000h
  87. jnz short afm09 ; TEB in system space, this is ok
  88. jmp short afm20 ; APCs not disabled --> fatal
  89. afm09: cmp [ecx].FmOwner, eax ; Already owned by this thread?
  90. je short afm21 ; Yes, error
  91. endif
  92. LOCK_DEC dword ptr [ecx].FmCount ; decrement lock count
  93. jz short afm_ret ; The owner? Yes, Done
  94. inc dword ptr [ecx].FmContention ; increment contention count
  95. if DBG
  96. push eax
  97. endif
  98. push ecx
  99. add ecx, FmEvent ; wait for ownership event
  100. stdCall _KeWaitForSingleObject,<ecx,WrExecutive,0,0,0> ;
  101. pop ecx
  102. if DBG
  103. pop eax
  104. endif
  105. afm_ret:
  106. ;
  107. ; Leave a notion of owner behind.
  108. ;
  109. ; Note: if you change this, change ExAcquireFastMutex.
  110. ;
  111. if DBG
  112. mov [ecx].FmOwner, eax ; Save in Fast Mutex
  113. else
  114. ;
  115. ; Use esp to track the owning thread for debugging purposes.
  116. ; !thread from kd will find the owning thread. Note that the
  117. ; owner isn't cleared on release, check if the mutex is owned
  118. ; first.
  119. ;
  120. mov [ecx].FmOwner, esp
  121. endif
  122. fstRet ExAcquireFastMutexUnsafe ; return
  123. if DBG
  124. afm20: stdCall _KeBugCheckEx,<IRQL_NOT_GREATER_OR_EQUAL,ecx,eax,039h,0>
  125. afm21: stdCall _KeBugCheckEx,<IRQL_NOT_GREATER_OR_EQUAL,ecx,eax,040h,0>
  126. endif
  127. int 3
  128. fstENDP ExAcquireFastMutexUnsafe
  129. ;++
  130. ;
  131. ; VOID
  132. ; FASTCALL
  133. ; ExReleaseFastMutexUnsafe (
  134. ; IN PFAST_MUTEX FastMutex
  135. ; )
  136. ;
  137. ; Routine description:
  138. ;
  139. ; This function releases ownership of a fast mutex, and does not
  140. ; restore IRQL to its previous value.
  141. ;
  142. ; Arguments:
  143. ;
  144. ; (ecx) = FastMutex - Supplies a pointer to a fast mutex.
  145. ;
  146. ; Return Value:
  147. ;
  148. ; None.
  149. ;
  150. ;--
  151. cPublicFastCall ExReleaseFastMutexUnsafe,1
  152. cPublicFpo 0,0
  153. if DBG
  154. push ecx
  155. stdCall _KeGetCurrentIrql
  156. pop ecx
  157. ;
  158. ; Caller must already be at APC_LEVEL or have APCs blocked.
  159. ;
  160. cmp al, APC_LEVEL
  161. mov eax,PCR[PcPrcbData+PbCurrentThread] ; grab the current thread 1st
  162. je short rfm09 ; APCs disabled, this is ok
  163. cmp dword ptr [eax]+ThKernelApcDisable, 0
  164. jne short rfm09 ; APCs disabled, this is ok
  165. cmp dword ptr [eax]+ThTeb, 0
  166. je short rfm09 ; No TEB ==> system thread, this is ok
  167. test dword ptr [eax]+ThTeb, 080000000h
  168. jnz short rfm09 ; TEB in system space, this is ok
  169. jmp short rfm20 ; APCs not disabled --> fatal
  170. rfm09: cmp [ecx].FmOwner, eax ; Owner == CurrentThread?
  171. jne short rfm_threaderror ; No, bugcheck
  172. or byte ptr [ecx].FmOwner, 1 ; not the owner anymore
  173. endif
  174. LOCK_ADD dword ptr [ecx].FmCount, 1 ; increment ownership count
  175. jng short rfm10 ; if ng, waiter present
  176. fstRet ExReleaseFastMutexUnsafe ; return
  177. rfm10: add ecx, FmEvent ; compute event address
  178. stdCall _KeSetEventBoostPriority,<ecx, 0> ; set ownerhsip event
  179. fstRet ExReleaseFastMutexUnsafe ; return
  180. if DBG
  181. rfm20: stdCall _KeBugCheckEx,<IRQL_NOT_GREATER_OR_EQUAL,ecx,eax,03ah,0>
  182. rfm_threaderror: stdCall _KeBugCheckEx,<IRQL_NOT_GREATER_OR_EQUAL,ecx,eax,03bh,0>
  183. endif
  184. int 3
  185. fstENDP ExReleaseFastMutexUnsafe
  186. _TEXT$00 ends
  187. end