Leaked source code of windows server 2003
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.

257 lines
6.3 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. include irqli386.inc
  32. .list
  33. EXTRNP _KeSetEventBoostPriority, 2
  34. EXTRNP _KeWaitForSingleObject, 5
  35. if DBG
  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. CurrentIrql
  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]+ThCombinedApcDisable, 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. jnz short afm10 ; The owner? No, go wait
  94. ;
  95. ; Leave a notion of owner behind.
  96. ;
  97. ; Note: if you change this, change ExAcquireFastMutex.
  98. ;
  99. if DBG
  100. mov [ecx].FmOwner, eax ; Save in Fast Mutex
  101. else
  102. ;
  103. ; Use esp to track the owning thread for debugging purposes.
  104. ; !thread from kd will find the owning thread. Note that the
  105. ; owner isn't cleared on release, check if the mutex is owned
  106. ; first.
  107. ;
  108. mov [ecx].FmOwner, esp
  109. endif
  110. fstRet ExAcquireFastMutexUnsafe ; return
  111. afm10:
  112. inc dword ptr [ecx].FmContention ; increment contention count
  113. if DBG
  114. push eax
  115. endif
  116. push ecx
  117. add ecx, FmEvent ; wait for ownership event
  118. stdCall _KeWaitForSingleObject,<ecx,WrMutex,0,0,0> ;
  119. pop ecx
  120. if DBG
  121. pop eax
  122. endif
  123. ;
  124. ; Leave a notion of owner behind.
  125. ;
  126. ; Note: if you change this, change ExAcquireFastMutex.
  127. ;
  128. if DBG
  129. mov [ecx].FmOwner, eax ; Save in Fast Mutex
  130. else
  131. ;
  132. ; Use esp to track the owning thread for debugging purposes.
  133. ; !thread from kd will find the owning thread. Note that the
  134. ; owner isn't cleared on release, check if the mutex is owned
  135. ; first.
  136. ;
  137. mov [ecx].FmOwner, esp
  138. endif
  139. fstRet ExAcquireFastMutexUnsafe ; return
  140. if DBG
  141. afm20: stdCall _KeBugCheckEx,<IRQL_NOT_GREATER_OR_EQUAL,ecx,eax,039h,0>
  142. afm21: stdCall _KeBugCheckEx,<IRQL_NOT_GREATER_OR_EQUAL,ecx,eax,040h,0>
  143. endif
  144. int 3
  145. fstENDP ExAcquireFastMutexUnsafe
  146. ;++
  147. ;
  148. ; VOID
  149. ; FASTCALL
  150. ; ExReleaseFastMutexUnsafe (
  151. ; IN PFAST_MUTEX FastMutex
  152. ; )
  153. ;
  154. ; Routine description:
  155. ;
  156. ; This function releases ownership of a fast mutex, and does not
  157. ; restore IRQL to its previous value.
  158. ;
  159. ; Arguments:
  160. ;
  161. ; (ecx) = FastMutex - Supplies a pointer to a fast mutex.
  162. ;
  163. ; Return Value:
  164. ;
  165. ; None.
  166. ;
  167. ;--
  168. cPublicFastCall ExReleaseFastMutexUnsafe,1
  169. cPublicFpo 0,0
  170. if DBG
  171. push ecx
  172. CurrentIrql
  173. pop ecx
  174. ;
  175. ; Caller must already be at APC_LEVEL or have APCs blocked.
  176. ;
  177. cmp al, APC_LEVEL
  178. mov eax,PCR[PcPrcbData+PbCurrentThread] ; grab the current thread 1st
  179. je short rfm09 ; APCs disabled, this is ok
  180. cmp dword ptr [eax]+ThCombinedApcDisable, 0
  181. jne short rfm09 ; APCs disabled, this is ok
  182. cmp dword ptr [eax]+ThTeb, 0
  183. je short rfm09 ; No TEB ==> system thread, this is ok
  184. test dword ptr [eax]+ThTeb, 080000000h
  185. jnz short rfm09 ; TEB in system space, this is ok
  186. jmp short rfm20 ; APCs not disabled --> fatal
  187. rfm09: cmp [ecx].FmOwner, eax ; Owner == CurrentThread?
  188. jne short rfm_threaderror ; No, bugcheck
  189. or byte ptr [ecx].FmOwner, 1 ; not the owner anymore
  190. endif
  191. LOCK_ADD dword ptr [ecx].FmCount, 1 ; increment ownership count
  192. jng short rfm10 ; if ng, waiter present
  193. fstRet ExReleaseFastMutexUnsafe ; return
  194. rfm10: add ecx, FmEvent ; compute event address
  195. stdCall _KeSetEventBoostPriority,<ecx, 0> ; set ownerhsip event
  196. fstRet ExReleaseFastMutexUnsafe ; return
  197. if DBG
  198. rfm20: stdCall _KeBugCheckEx,<IRQL_NOT_GREATER_OR_EQUAL,ecx,eax,03ah,0>
  199. rfm_threaderror: stdCall _KeBugCheckEx,<IRQL_NOT_GREATER_OR_EQUAL,ecx,eax,03bh,0>
  200. endif
  201. int 3
  202. fstENDP ExReleaseFastMutexUnsafe
  203. _TEXT$00 ends
  204. end