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.

170 lines
4.0 KiB

  1. if NT_INST
  2. else
  3. TITLE "Spin Locks"
  4. ;++
  5. ;
  6. ; Copyright (c) 1989 Microsoft Corporation
  7. ;
  8. ; Module Name:
  9. ;
  10. ; spindbg.asm
  11. ;
  12. ; Abstract:
  13. ;
  14. ; Author:
  15. ;
  16. ; Bryan Willman (bryanwi) 13 Dec 89
  17. ;
  18. ; Environment:
  19. ;
  20. ; Kernel mode only.
  21. ;
  22. ; Revision History:
  23. ;
  24. ;--
  25. PAGE
  26. .386p
  27. include ks386.inc
  28. include callconv.inc ; calling convention macros
  29. include mac386.inc
  30. include irqli386.inc
  31. if DBG
  32. EXTRNP _KeBugCheckEx,5
  33. ifdef DBGMP
  34. EXTRNP _KiPollDebugger,0
  35. endif
  36. extrn _KeTickCount:DWORD
  37. extrn _KiSpinlockTimeout:DWORD
  38. endif
  39. _TEXT$00 SEGMENT DWORD PUBLIC 'CODE'
  40. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  41. ;++
  42. ;
  43. ; VOID
  44. ; Kii386SpinOnSpinLock (
  45. ; IN PKSPIN_LOCK SpinLock
  46. ; IN ULONG Flag
  47. ; )
  48. ;
  49. ; Routine Description:
  50. ;
  51. ; This function is called on a debug build to spin on a spinlock.
  52. ; It is invoked by the DEBUG version of SPIN_ON_SPINLOCK macro.
  53. ;
  54. ; Warning:
  55. ;
  56. ; Not called with C calling conventions
  57. ; Does not destroy any register
  58. ;
  59. ;--
  60. cPublicProc Kii386SpinOnSpinLock,2
  61. if DBG
  62. cPublicFpo 2,2
  63. push eax
  64. push ebx
  65. mov eax, [esp+12] ; (eax) = LockAddress
  66. mov ebx, PCR[PcPrcbData.PbCurrentThread]
  67. or ebx, 1 ; or on busy bit
  68. cmp ebx, [eax] ; current thread the owner?
  69. je short ssl_sameid ; Yes, go abort
  70. ssl_10:
  71. mov ebx, _KeTickCount ; Current time
  72. add ebx, _KiSpinlockTimeout ; wait n ticks
  73. ifdef DBGMP
  74. test byte ptr [esp+16], 2 ; poll debugger while waiting?
  75. jnz short ssl_30
  76. endif
  77. ;
  78. ; Spin while watching KeTickCount
  79. ;
  80. ssl_20: YIELD
  81. cmp _KeTickCount, ebx ; check current time
  82. jnc short ssl_timeout ; NC, too many ticks have gone by
  83. test dword ptr [eax], 1
  84. jnz short ssl_20
  85. ssl_exit:
  86. pop ebx ; Spinlock is not busy, return
  87. pop eax
  88. stdRET Kii386SpinOnSpinLock
  89. ifdef DBGMP
  90. ;
  91. ; Spin while watching KeTickCount & poll debugger
  92. ;
  93. ssl_30: YIELD
  94. cmp _KeTickCount, ebx ; check current time
  95. jnc short ssl_timeout ; overflowed
  96. stdCall _KiPollDebugger
  97. test dword ptr [eax], 1
  98. jnz short ssl_30
  99. pop ebx ; Spinlock is not busy, return
  100. pop eax
  101. stdRET Kii386SpinOnSpinLock
  102. endif
  103. ;
  104. ; Out of line expection conditions
  105. ;
  106. ssl_sameid:
  107. test byte ptr [esp+16], 1 ; ID check enabled?
  108. jz short ssl_10 ; no, continue
  109. push eax
  110. CurrentIrql ; Get current IRQL
  111. cmp al, SYNCH_LEVEL ; Above synch_level we may seen the same
  112. pop eax ; thread on two different processors
  113. jg ssl_10
  114. ; recursed on lock, abort
  115. stdCall _KeBugCheckEx,<SPIN_LOCK_ALREADY_OWNED,eax,0,0,0>
  116. ssl_timeout:
  117. test byte ptr [esp+16], 4 ; Timeout check enabled?
  118. jz short ssl_10 ; no, continue
  119. CurrentIrql ; Check to see what level we're spinning at
  120. cmp al, DISPATCH_LEVEL
  121. mov eax, [esp+12] ; restore eax
  122. jc short ssl_10 ; if < dispatch_level, don't timeout
  123. test dword ptr [eax], 1 ; Check to see if spinlock was freed
  124. jz short ssl_exit
  125. public SpinLockSpinningForTooLong
  126. SpinLockSpinningForTooLong:
  127. int 3 ; Stop here
  128. jmp short ssl_10 ; re-wait
  129. else ; DBG
  130. stdRET Kii386SpinOnSpinLock
  131. endif
  132. stdENDP Kii386SpinOnSpinLock,2
  133. _TEXT$00 ends
  134. endif ; NT_INST
  135. end