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.

284 lines
6.2 KiB

  1. ;++
  2. ;
  3. ; Copyright (c) 1989 Microsoft Corporation
  4. ;
  5. ; Module Name:
  6. ;
  7. ; mac386.inc - 386 machine specific assembler macros
  8. ;
  9. ; Abstract:
  10. ;
  11. ; This module contains 386 machine specific (assembler) macros
  12. ; applicable to code outside the kernel. Note that
  13. ; ACQUIRE_SPINLOCK_DIRECT assumes the PCR is handy, so it won't
  14. ; work in user mode (with debugging turned on.)
  15. ;
  16. ; Author:
  17. ;
  18. ; Bryan Willman (bryanwi) 1 Aug 90
  19. ;
  20. ;++
  21. ;
  22. ; YIELD
  23. ;
  24. ; Macro Description:
  25. ;
  26. ; This macro implements the yield instruction
  27. ;--
  28. YIELD macro
  29. ifndef NT_UP
  30. db 0f3h
  31. db 090h
  32. endif
  33. endm
  34. if NT_INST
  35. else
  36. ;++
  37. ;
  38. ; ACQUIRE_SPINLOCK LockAddress, SpinLabel
  39. ;
  40. ; Macro Description:
  41. ;
  42. ; This macro acquires a kernel spin lock.
  43. ;
  44. ; N.B. This macro assumes that the current IRQL is set properly.
  45. ; It neither raises nor lowers IRQL.
  46. ;
  47. ; Arguments:
  48. ;
  49. ; (KSPIN_LOCK) LockAddress - address of SpinLock value
  50. ; SpinLabel - if acquire spinlock fail, the label to perform the
  51. ; spin checking. It could be simply a "label" or
  52. ; "short label" which means the label is within 128
  53. ; bytes in distant.
  54. ;
  55. ; NoChecking - Not blank, if no debugging code should be generated.
  56. ;--
  57. ACQUIRE_SPINLOCK macro LockAddress, SpinLabel, NoChecking
  58. .errb <LockAddress>
  59. .errb <SpinLabel>
  60. ifndef NT_UP
  61. ;
  62. ; Attempt to assert the lock
  63. ;
  64. lock bts dword ptr [LockAddress], 0 ; test and set the spinlock
  65. jc SpinLabel ; spinlock owned, go SpinLabe
  66. if DBG
  67. ifb <NoChecking>
  68. push edi ; save edi
  69. mov edi,fs:PcPrcb
  70. mov edi, [edi].PbCurrentThread
  71. or edi, 1 ; spinlock owned
  72. mov [LockAddress], edi ; remember current thread
  73. pop edi ; restore edi
  74. endif ; NoChecking
  75. endif ; DBG
  76. endif ; NT_UP
  77. endm
  78. ;++
  79. ;
  80. ; SPIN_ON_SPINLOCK LockAddress, AcquireLabel
  81. ;
  82. ; Macro Description:
  83. ;
  84. ; This macro spins on a kernel spin lock.
  85. ;
  86. ; N.B. This macro assumes that the current IRQL is set properly.
  87. ; It neither raises nor lowers IRQL.
  88. ;
  89. ; Arguments:
  90. ;
  91. ; (KSPIN_LOCK) LockAddress - address of a SpinLock value
  92. ;
  93. ; SpinLabel - if the test on cleared spinlock sucess, the label
  94. ; to assert the spin lock. It could be simply a
  95. ; "label" or "short label" which means the label is
  96. ; within 128 bytes in distance.
  97. ;
  98. ; NoChecking - Not blank, if no debugging code should be generated.
  99. ;--
  100. SPIN_ON_SPINLOCK macro LockAddress, AcquireLabel, NoChecking, PollDebugger, NoTimeout
  101. local a,flag ; define a local label
  102. .errb <LockAddress>
  103. .errb <AcquireLabel>
  104. ifndef NT_UP
  105. if DBG
  106. EXTRNP Kii386SpinOnSpinLock,2
  107. flag = 0
  108. ifb <NoChecking>
  109. flag = flag + 1
  110. endif
  111. ifnb <Polldebugger>
  112. flag = flag + 2
  113. endif
  114. ifb <NoTimeout>
  115. flag = flag + 4
  116. endif
  117. stdCall Kii386SpinOnSpinLock,<LockAddress,flag>
  118. jmp AcquireLabel
  119. else ; DBG
  120. ;
  121. ; Non-Debug version
  122. ;
  123. a: test dword ptr [LockAddress], 1 ; Was spinlock cleared?
  124. jz AcquireLabel ; Yes, go get it
  125. YIELD
  126. jmp short a
  127. endif ; DBG
  128. endif ; NT_UP
  129. endm
  130. ;++
  131. ;
  132. ; TEST_SPINLOCK LockAddress, BusyLabel
  133. ;
  134. ; Macro Description:
  135. ;
  136. ; This macro tests a kernel spin lock to see if it's busy.
  137. ; If it's not busy, ACQUIRE_SPINLOCK still needs to be called
  138. ; to obtain the spinlock in a locked manner.
  139. ;
  140. ; Arguments:
  141. ;
  142. ; (KSPIN_LOCK) LockAddress - address of a SpinLock value
  143. TEST_SPINLOCK macro LockAddress, BusyLabel
  144. test dword ptr [LockAddress], 1 ; spinlock clear?
  145. jnz BusyLabel ; No, then busy
  146. endm
  147. ;++
  148. ;
  149. ; RELEASE_SPINLOCK LockAddress
  150. ;
  151. ; Macro Description:
  152. ;
  153. ; This macro releases a kernel spin lock.
  154. ;
  155. ; N.B. This macro assumes that the current IRQL is set properly.
  156. ; It neither raises nor lowers IRQL.
  157. ;
  158. ; Arguments:
  159. ;
  160. ; (KSPIN_LOCK) LockAddress - Supplies an address to a spin lock value
  161. ; NoChecking - Not blank, if no debugging code should be generated.
  162. ;--
  163. RELEASE_SPINLOCK macro LockAddress, NoChecking
  164. local a
  165. .errb <LockAddress>
  166. ifndef NT_UP
  167. if DBG
  168. ifb <NoChecking>
  169. EXTRNP _KeBugCheckEx,5
  170. push edi ; save edi
  171. mov edi,fs:PcPrcb
  172. mov edi,[edi].PbCurrentThread
  173. or edi, 1 ; assume current thread owns the lock
  174. cmp edi, [LockAddress] ; Does current thread own the lock?
  175. pop edi ; restore edi
  176. jz short a ; if z, yes, goto a and release lock
  177. stdCall _KeBugCheckEx,<SPIN_LOCK_NOT_OWNED,LockAddress,0,0,0>
  178. a:
  179. endif
  180. mov dword ptr [LockAddress], 0
  181. else
  182. mov byte ptr [LockAddress], 0
  183. endif ; DBG
  184. endif ; NT_UP
  185. endm
  186. endif
  187. if NT_INST
  188. ;
  189. ; These are the instrumentation version of the above functions.
  190. ; internal use only
  191. ;
  192. ACQUIRE_SPINLOCK macro LockAddress, SpinLabel, NoChecking
  193. EXTRNP KiInst_AcquireSpinLock,0
  194. ifidni <&LockAddress>, <eax>
  195. stdCall KiInst_AcquireSpinLock
  196. else
  197. push eax
  198. mov eax, LockAddress
  199. stdCall KiInst_AcquireSpinLock
  200. pop eax
  201. endif
  202. jc SpinLabel
  203. endm
  204. SPIN_ON_SPINLOCK macro LockAddress, AcquireLabel, NoChecking, PollDebugger
  205. EXTRNP KiInst_SpinOnSpinLock,0
  206. ifidni <&LockAddress>, <eax>
  207. stdCall KiInst_SpinOnSpinLock
  208. else
  209. push eax
  210. mov eax, LockAddress
  211. stdCall KiInst_SpinOnSpinLock
  212. pop eax
  213. endif
  214. jmp AcquireLabel
  215. endm
  216. TEST_SPINLOCK macro LockAddress, BusyLabel
  217. EXTRNP KiInst_TestSpinLock,0
  218. ifidni <&LockAddress>, <eax>
  219. stdCall KiInst_TestSpinLock
  220. else
  221. push eax
  222. mov eax, LockAddress
  223. stdCall KiInst_TestSpinLock
  224. pop eax
  225. endif
  226. jnc AcquireLabel
  227. endm
  228. RELEASE_SPINLOCK macro LockAddress, NoChecking
  229. EXTRNP KiInst_ReleaseSpinLock,0
  230. ifidni <&LockAddress>, <eax>
  231. stdCall KiInst_ReleaseSpinLock
  232. else
  233. push eax
  234. mov eax, LockAddress
  235. stdCall KiInst_ReleaseSpinLock
  236. pop eax
  237. endif
  238. endm
  239. endif