NT4/private/ntos/ex/mips/fmutex.s
2020-09-30 17:12:29 +02:00

467 lines
15 KiB
ArmAsm
Raw 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.

// TITLE("Fast Mutex Support")
//++
//
// Copyright (c) 1994 Microsoft Corporation
//
// Module Name:
//
// fmutex.s
//
// Abstract:
//
// This module implements the code necessary to acquire and release fast
// mutxes.
//
//
// Author:
//
// David N. Cutler (davec) 13-Apr-1994
//
// Environment:
//
// Kernel mode only.
//
// Revision History:
//
//--
#include "ksmips.h"
SBTTL("Acquire Fast Mutex")
//++
//
// VOID
// ExAcquireFastMutex (
// IN PFAST_MUTEX FastMutex
// )
//
// Routine Description:
//
// This function acquires ownership of a fast mutex and raises IRQL to
// APC level.
//
// Arguments:
//
// FastMutex (a0) - Supplies a pointer to a fast mutex.
//
// Return Value:
//
// None.
//
//--
.struct 0
.space 4 * 4 // argment save area
FmTime: .space 4 // wait timeout pointer
FmA0: .space 4 // saved fast mutex address
FmIrql: .space 4 // old IRQL value
FmRa: .space 4 // saved return address
FastMutexFrameLength: // frame length
NESTED_ENTRY(ExAcquireFastMutex, FastMutexFrameLength, zero)
subu sp,sp,FastMutexFrameLength // allocate stack frame
sw ra,FmRa(sp) // save return address
PROLOGUE_END
//
// Raise IRQL to APC_LEVEL.
//
li a1,APC_LEVEL // set new IRQL level
lbu t0,KiPcr + PcIrqlTable(a1) // get translation table entry value
li t1,~(0xff << PSR_INTMASK) // get interrupt enable mask
sll t0,t0,PSR_INTMASK // shift table entry into position
lbu t2,KiPcr + PcCurrentIrql(zero) // get current IRQL
DISABLE_INTERRUPTS(t3) // disable interrupts
and t3,t3,t1 // clear current interrupt enables
or t3,t3,t0 // set new interrupt enables
sb a1,KiPcr + PcCurrentIrql(zero) // set new IRQL
ENABLE_INTERRUPTS(t3) // enable interrupts
//
// Decrement ownership count.
//
lw t6,KiPcr + PcCurrentThread(zero) // get current thread address
10: ll t4,FmCount(a0) // get ownership count
subu t5,t4,1 // decrement ownership count
sc t5,FmCount(a0) // conditionally store ownership count
beq zero,t5,10b // if eq, store conditional failed
blez t4,20f // if lez, mutex is already owned
sb t2,FmOldIrql(a0) // store old IRQL
sw t6,FmOwner(a0) // set owner thread address
addu sp,sp,FastMutexFrameLength // deallocate stack frame
j ra // return
//
// Fast mutex is currently owned by another thread. Increment the contention
// count and wait for ownership.
//
20: sb t2,FmIrql(sp) // save old IRQL
sw a0,FmA0(sp) // save address of fast mutex
lw t0,FmContention(a0) // increment contention count
addu t0,t0,1 //
sw t0,FmContention(a0) //
#if DBG
lw t0,FmOwner(a0) // get owner thread address
bne t0,t6,30f // if ne, thread not owner
jal DbgBreakPoint // break
#endif
30: sw zero,FmTime(sp) // set NULL timeout pointer
li a3,FALSE // set nonalertable wait
li a2,KernelMode // set mode of wait
li a1,Executive // set reason for wait
addu a0,a0,FmEvent // compute address of event
jal KeWaitForSingleObject // wait for ownership
lw a0,FmA0(sp) // get address of fast mutex
lbu a1,FmIrql(sp) // get old IRQL value
lw a2,KiPcr + PcCurrentThread(zero) // get current thread address
sb a1,FmOldIrql(a0) // save old IRQL in fast mutex
sw a2,FmOwner(a0) // set owner thread address
lw ra,FmRa(sp) // restore return address
addu sp,sp,FastMutexFrameLength // deallocate stack frame
j ra // return
.end ExAcquireFastMutex
SBTTL("Release Fast Mutex")
//++
//
// VOID
// ExReleaseFastMutex (
// IN PFAST_MUTEX FastMutex
// )
//
// Routine Description:
//
// This function releases ownership to a fast mutex and lowers IRQL to
// its previous level.
//
// Arguments:
//
// FastMutex (a0) - Supplies a pointer to a fast mutex.
//
// Return Value:
//
// None.
//
//--
NESTED_ENTRY(ExReleaseFastMutex, FastMutexFrameLength, zero)
subu sp,sp,FastMutexFrameLength // allocate stack frame
sw ra,FmRa(sp) // save return address
PROLOGUE_END
//
// Increment ownership count and release waiter if contention.
//
lbu a1,FmOldIrql(a0) // get old IRQL value
sw zero,FmOwner(a0) // clear owner thread address
10: ll t0,FmCount(a0) // get ownership count
addu t1,t0,1 // increment ownership count
sc t1,FmCount(a0) // conditionally store ownership count
beq zero,t1,10b // if eq, store conditional failed
beq zero,t0,20f // if eq, no waiter is present
//
// There is contention for the fast mutex. Wake up a waiting thread and
// boost its priority to the priority of the current thread.
//
sw a0,FmA0(sp) // save address of fast mutex
sb a1,FmIrql(sp) // save old IRQL value
addu a1,a0,FmOwner // compute address to store owner
addu a0,a0,FmEvent // compute address of event
jal KeSetEventBoostPriority // set event and boost priority
lw a0,FmA0(sp) // restore fast mutex address
lbu a1,FmIrql(sp) // restore old IRQL value
lw ra,FmRa(sp) // restore return address
//
// Lower IRQL to its previous value.
//
20: lbu t0,KiPcr + PcIrqlTable(a1) // get translation table entry value
li t1,~(0xff << PSR_INTMASK) // get interrupt enable mask
sll t0,t0,PSR_INTMASK // shift table entry into position
DISABLE_INTERRUPTS(t2) // disable interrupts
and t2,t2,t1 // clear current interrupt enables
or t2,t2,t0 // set new interrupt enables
sb a1,KiPcr + PcCurrentIrql(zero) // set new IRQL
ENABLE_INTERRUPTS(t2) // enable interrupts
addu sp,sp,FastMutexFrameLength // deallocate stack frame
j ra // return
.end ExReleaseFastMutex
SBTTL("Try To Acquire Fast Mutex")
//++
//
// BOOLEAN
// ExTryToAcquireFastMutex (
// IN PFAST_MUTEX FastMutex
// )
//
// Routine Description:
//
// This function attempts to acquire ownership of a fast mutex, and if
// successful, raises IRQL to APC level.
//
// Arguments:
//
// FastMutex (a0) - Supplies a pointer to a fast mutex.
//
// Return Value:
//
// If the fast mutex was successfuly acquired, then a value of TRUE
// is returned as the function vlaue. Otherwise, a value of FALSE is
// returned.
//
//--
LEAF_ENTRY(ExTryToAcquireFastMutex)
li a1,APC_LEVEL // set new IRQL level
lbu t0,KiPcr + PcIrqlTable(a1) // get translation table entry value
li t1,~(0xff << PSR_INTMASK) // get interrupt enable mask
sll t0,t0,PSR_INTMASK // shift table entry into position
lbu t2,KiPcr + PcCurrentIrql(zero) // get current IRQL
DISABLE_INTERRUPTS(t3) // disable interrupts
//
// Decrement ownership count if and only if the fast mutex is not currently
// owned.
//
lw t5,KiPcr + PcCurrentThread(zero) // get current thread address
10: ll t4,FmCount(a0) // get ownership count
subu v0,t4,1 // decrement ownership count
blez t4,20f // if lez, mutex is already owned
sc v0,FmCount(a0) // conditionally store ownership count
beq zero,v0,10b // if eq, store conditional failed
and t3,t3,t1 // clear current interrupt enables
or t3,t3,t0 // set new interrupt enables
sb a1,KiPcr + PcCurrentIrql(zero) // set new IRQL
ENABLE_INTERRUPTS(t3) // enable interrupts
sb t2,FmOldIrql(a0) // store old IRQL
sw t5,FmOwner(a0) // set owner thread address
j ra // return
//
// Fast mutex is currently owned by another thread. Enable interrupts and
// return FALSE.
//
20: ENABLE_INTERRUPTS(t3) // enable interrupts
li v0,FALSE // set return value
j ra // return
.end ExTryToAcquireFastMutex
SBTTL("Acquire Fast Mutex Unsafe")
//++
//
// VOID
// ExAcquireFastMutexUnsafe (
// IN PFAST_MUTEX FastMutex
// )
//
// Routine Description:
//
// This function acquires ownership of a fast mutex, but does not raise
// IRQL to APC level.
//
// Arguments:
//
// FastMutex (a0) - Supplies a pointer to a fast mutex.
//
// Return Value:
//
// None.
//
//--
NESTED_ENTRY(ExAcquireFastMutexUnsafe, FastMutexFrameLength, zero)
subu sp,sp,FastMutexFrameLength // allocate stack frame
sw ra,FmRa(sp) // save return address
PROLOGUE_END
//
// Decrement ownership count.
//
lw t0,KiPcr + PcCurrentThread(zero) // get current thread address
10: ll t1,FmCount(a0) // get ownership count
subu t2,t1,1 // decrement ownership count
sc t2,FmCount(a0) // conditionally store ownership count
beq zero,t2,10b // if eq, store conditional failed
blez t1,20f // if lez, mutex is already owned
sw t0,FmOwner(a0) // set owner thread address
addu sp,sp,FastMutexFrameLength // deallocate stack frame
j ra // return
//
// Fast mutex is currently owned by another thread. Increment the contention
// count and wait for ownership.
//
20: sw a0,FmA0(sp) // save address of fast mutex
lw t1,FmContention(a0) // increment contention count
addu t1,t1,1 //
sw t1,FmContention(a0) //
#if DBG
lw t1,FmOwner(a0) // get owner thread address
bne t0,t1,30f // if ne, thread not owner
jal DbgBreakPoint // break
#endif
30: sw zero,FmTime(sp) // set NULL timeout pointer
li a3,FALSE // set nonalertable wait
li a2,KernelMode // set mode of wait
li a1,Executive // set reason for wait
addu a0,a0,FmEvent // compute address of event
jal KeWaitForSingleObject // wait for ownership
lw a0,FmA0(sp) // get address of fast mutex
lw a1,KiPcr + PcCurrentThread(zero) // get current thread address
sw a1,FmOwner(a0) // set owner thread address
lw ra,FmRa(sp) // restore return address
addu sp,sp,FastMutexFrameLength // deallocate stack frame
j ra // return
.end ExAcquireFastMutexUnsafe
SBTTL("Release Fast Mutex Unsafe")
//++
//
// VOID
// ExReleaseFastMutexUnsafe (
// IN PFAST_MUTEX FastMutex
// )
//
// Routine Description:
//
// This function releases ownership of a fast mutex, and does not
// restore IRQL to its previous value.
//
// Arguments:
//
// FastMutex (a0) - Supplies a pointer to a fast mutex.
//
// Return Value:
//
// None.
//
//--
NESTED_ENTRY(ExReleaseFastMutexUnsafe, FastMutexFrameLength, zero)
subu sp,sp,FastMutexFrameLength // allocate stack frame
sw ra,FmRa(sp) // save return address
PROLOGUE_END
//
// Increment ownership count and release waiter if contention.
//
sw zero,FmOwner(a0) // clear owner thread address
10: ll t0,FmCount(a0) // get ownership count
addu t1,t0,1 // increment ownership count
sc t1,FmCount(a0) // conditionally store ownership count
beq zero,t1,10b // if eq, store conditional failed
beq zero,t0,20f // if eq, no waiter is present
//
// There is contention for the fast mutex. Wake up a waiting thread and
// boost its priority to the priority of the current thread.
//
addu a1,a0,FmOwner // compute address to store owner
addu a0,a0,FmEvent // compute address of event
jal KeSetEventBoostPriority // set event and boost priority
lw ra,FmRa(sp) // restore return address
20: addu sp,sp,FastMutexFrameLength // deallocate stack frame
j ra // return
.end ExReleaseFastMutexUnsafe
SBTTL("Try To Acquire Fast Mutex Unsafe")
//++
//
// BOOLEAN
// ExTryToAcquireFastMutexUnsafe (
// IN PFAST_MUTEX FastMutex
// )
//
// Routine Description:
//
// This function attempts to acquire ownership of a fast mutex, and if
// successful, does not raise IRQL to APC level.
//
// Arguments:
//
// FastMutex (a0) - Supplies a pointer to a fast mutex.
//
// Return Value:
//
// If the fast mutex was successfuly acquired, then a value of TRUE
// is returned as the function vlaue. Otherwise, a value of FALSE is
// returned.
//
//--
#if 0
LEAF_ENTRY(ExTryToAcquireFastMutexUnsafe)
//
// Decrement ownership count if and only if the fast mutex is not currently
// owned.
//
lw t0,KiPcr + PcCurrentThread(zero) // get current thread address
10: ll t1,FmCount(a0) // get ownership count
subu v0,t1,1 // decrement ownership count
blez t1,20f // if lez, mutex is already owned
sc v0,FmCount(a0) // conditionally store ownership count
beq zero,v0,10b // if eq, store conditional failed
sw t0,FmOwner(a0) // set owner thread address
j ra // return
//
// Fast mutex is currently owned by another thread.
//
20: li v0,FALSE // set return value
j ra // return
.end ExTryToAcquireFastMutexUnsafe
#endif