NT4/public/sdk/inc/mac386.inc

268 lines
6.0 KiB
PHP
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;++
;
; Copyright (c) 1989 Microsoft Corporation
;
; Module Name:
;
; mac386.inc - 386 machine specific assembler macros
;
; Abstract:
;
; This module contains 386 machine specific (assembler) macros
; applicable to code outside the kernel. Note that
; ACQUIRE_SPINLOCK_DIRECT assumes the PCR is handy, so it won't
; work in user mode (with debugging turned on.)
;
; Author:
;
; Bryan Willman (bryanwi) 1 Aug 90
;
if NT_INST
else
;++
;
; ACQUIRE_SPINLOCK LockAddress, SpinLabel
;
; Macro Description:
;
; This macro acquires a kernel spin lock.
;
; N.B. This macro assumes that the current IRQL is set properly.
; It neither raises nor lowers IRQL.
;
; Arguments:
;
; (KSPIN_LOCK) LockAddress - address of SpinLock value
; SpinLabel - if acquire spinlock fail, the label to perform the
; spin checking. It could be simply a "label" or
; "short label" which means the label is within 128
; bytes in distant.
;
; NoChecking - Not blank, if no debugging code should be generated.
;--
ACQUIRE_SPINLOCK macro LockAddress, SpinLabel, NoChecking
.errb <LockAddress>
.errb <SpinLabel>
ifndef NT_UP
;
; Attempt to assert the lock
;
lock bts dword ptr [LockAddress], 0 ; test and set the spinlock
jc SpinLabel ; spinlock owned, go SpinLabe
if DBG
ifb <NoChecking>
push edi ; save edi
mov edi,fs:PcPrcb
mov edi, [edi].PbCurrentThread
or edi, 1 ; spinlock owned
mov [LockAddress], edi ; remember current thread
pop edi ; restore edi
endif ; NoChecking
endif ; DBG
endif ; NT_UP
endm
;++
;
; SPIN_ON_SPINLOCK LockAddress, AcquireLabel
;
; Macro Description:
;
; This macro spins on a kernel spin lock.
;
; N.B. This macro assumes that the current IRQL is set properly.
; It neither raises nor lowers IRQL.
;
; Arguments:
;
; (KSPIN_LOCK) LockAddress - address of a SpinLock value
;
; SpinLabel - if the test on cleared spinlock sucess, the label
; to assert the spin lock. It could be simply a
; "label" or "short label" which means the label is
; within 128 bytes in distance.
;
; NoChecking - Not blank, if no debugging code should be generated.
;--
SPIN_ON_SPINLOCK macro LockAddress, AcquireLabel, NoChecking, PollDebugger, NoTimeout
local a,flag ; define a local label
.errb <LockAddress>
.errb <AcquireLabel>
ifndef NT_UP
if DBG
EXTRNP Kii386SpinOnSpinLock,2
flag = 0
ifb <NoChecking>
flag = flag + 1
endif
ifnb <Polldebugger>
flag = flag + 2
endif
ifb <NoTimeout>
flag = flag + 4
endif
stdCall Kii386SpinOnSpinLock,<LockAddress,flag>
jmp AcquireLabel
else ; DBG
;
; Non-Debug version
;
a: test dword ptr [LockAddress], 1 ; Was spinlock cleared?
jz AcquireLabel ; Yes, go get it
jmp short a
endif ; DBG
endif ; NT_UP
endm
;++
;
; TEST_SPINLOCK LockAddress, BusyLabel
;
; Macro Description:
;
; This macro tests a kernel spin lock to see if it's busy.
; If it's not busy, ACQUIRE_SPINLOCK still needs to be called
; to obtain the spinlock in a locked manner.
;
; Arguments:
;
; (KSPIN_LOCK) LockAddress - address of a SpinLock value
TEST_SPINLOCK macro LockAddress, BusyLabel
test dword ptr [LockAddress], 1 ; spinlock clear?
jnz BusyLabel ; No, then busy
endm
;++
;
; RELEASE_SPINLOCK LockAddress
;
; Macro Description:
;
; This macro releases a kernel spin lock.
;
; N.B. This macro assumes that the current IRQL is set properly.
; It neither raises nor lowers IRQL.
;
; Arguments:
;
; (KSPIN_LOCK) LockAddress - Supplies an address to a spin lock value
; NoChecking - Not blank, if no debugging code should be generated.
;--
RELEASE_SPINLOCK macro LockAddress, NoChecking
local a
.errb <LockAddress>
ifndef NT_UP
if DBG
ifb <NoChecking>
EXTRNP _KeBugCheck,1
push edi ; save edi
mov edi,fs:PcPrcb
mov edi,[edi].PbCurrentThread
or edi, 1 ; assume current thread owns the lock
cmp edi, [LockAddress] ; Does current thread own the lock?
pop edi ; restore edi
jz short a ; if z, yes, goto a and release lock
stdCall _KeBugCheck,<LockAddress> ; Never return ...
a:
endif
mov dword ptr [LockAddress], 0
else
mov byte ptr [LockAddress], 0
endif ; DBG
endif ; NT_UP
endm
endif
if NT_INST
;
; These are the instrumentation version of the above functions.
; internal use only
;
ACQUIRE_SPINLOCK macro LockAddress, SpinLabel, NoChecking
EXTRNP KiInst_AcquireSpinLock,0
ifidni <&LockAddress>, <eax>
stdCall KiInst_AcquireSpinLock
else
push eax
mov eax, LockAddress
stdCall KiInst_AcquireSpinLock
pop eax
endif
jc SpinLabel
endm
SPIN_ON_SPINLOCK macro LockAddress, AcquireLabel, NoChecking, PollDebugger
EXTRNP KiInst_SpinOnSpinLock,0
ifidni <&LockAddress>, <eax>
stdCall KiInst_SpinOnSpinLock
else
push eax
mov eax, LockAddress
stdCall KiInst_SpinOnSpinLock
pop eax
endif
jmp AcquireLabel
endm
TEST_SPINLOCK macro LockAddress, BusyLabel
EXTRNP KiInst_TestSpinLock,0
ifidni <&LockAddress>, <eax>
stdCall KiInst_TestSpinLock
else
push eax
mov eax, LockAddress
stdCall KiInst_TestSpinLock
pop eax
endif
jnc AcquireLabel
endm
RELEASE_SPINLOCK macro LockAddress, NoChecking
EXTRNP KiInst_ReleaseSpinLock,0
ifidni <&LockAddress>, <eax>
stdCall KiInst_ReleaseSpinLock
else
push eax
mov eax, LockAddress
stdCall KiInst_ReleaseSpinLock
pop eax
endif
endm
endif