windows-nt/Source/XPSP1/NT/base/ntos/ex/alpha/fmutex.s
2020-09-26 16:20:57 +08:00

525 lines
14 KiB
ArmAsm
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.

// TITLE("Alpha 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:
//
// John Vert (jvert) 14-Apr-1994
//
// Environment:
//
// Kernel mode only.
//
// Revision History:
//
//--
#include "ksalpha.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
FmA0: .space 8 // saved fast mutex address
FmIrql: .space 4 // old IRQL value
.space 4 // fill
FmRa: .space 8 // saved return address
.space 8 // fill
FastMutexFrameLength: // frame length
NESTED_ENTRY(ExAcquireFastMutex, FastMutexFrameLength, zero)
lda sp, -FastMutexFrameLength(sp) // allocate stack frame
stq ra, FmRa(sp) // save return address
PROLOGUE_END
//
// Raise IRQL to APC_LEVEL
//
bis a0, zero, t0 // save address of fast mutex
bis zero, APC_LEVEL, a0 // set new IRQL level
SWAP_IRQL // raise IRQL
//
// Decrement ownership count.
//
10: ldl_l t4, FmCount(t0) // get ownership count
subl t4, 1, t5 // decrement ownership count
stl_c t5, FmCount(t0) // conditionally store ownership count
beq t5, 15f // if eq, conditional store failed
ble t4, 20f // if le, mutex is already owned
#if !defined(NT_UP)
mb // synchronize memory access
#endif
stl v0, FmOldIrql(t0) // save previous IRQL
GET_CURRENT_THREAD // get current thread address
STP v0, FmOwner(t0) // set owner thread address
lda sp, FastMutexFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
//
// Store conditional attempt failed.
//
15: br zero, 10b // retry
//
// Fast mutex is currently owned by another thread. Increment the contention
// count and wait for ownership.
//
20: stl v0, FmIrql(sp) // save previous IRQL
STP t0, FmA0(sp) // save address of fast mutex
ldl t1, FmContention(t0) // increment contention count
addl t1, 1, t2 //
stl t2, FmContention(t0) //
bis zero, zero, a4 // set NULL timeout pointer
bis zero, FALSE, a3 // set nonalertable wait
bis zero, KernelMode, a2 // set mode of wait
bis zero, Executive, a1 // set reason for wait
ADDP t0, FmEvent, a0 // compute address of event
bsr ra, KeWaitForSingleObject // wait for ownership
LDP t0, FmA0(sp) // get address of fast mutex
ldl a1, FmIrql(sp) // get old IRQL value
stl a1, FmOldIrql(t0) // save old IRQL value in fast mutex
GET_CURRENT_THREAD // get current thread address
STP v0, FmOwner(t0) // set owner thread address
ldq ra, FmRa(sp) // restore return address
lda sp, FastMutexFrameLength(sp) // deallocate stack frame
ret zero, (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)
lda sp, -FastMutexFrameLength(sp) // allocate stack frame
stq ra, FmRa(sp) // save return address
PROLOGUE_END
ldl a1, FmOldIrql(a0) // get old IRQL value
STP zero, FmOwner(a0) // clear owner thread address
//
// Synchronize all previous writes before the mutex is released.
//
#if !defined(NT_UP)
mb // synchronize memory access
#endif
//
// Increment ownership count and release waiter if contention.
//
10: ldl_l t0, FmCount(a0) // get ownership count
addl t0, 1, t1 // increment ownership count
stl_c t1, FmCount(a0) // conditionally store ownership count
beq t1, 15f // if eq, store conditional failed
bne t0, 30f // if ne, a waiter is present
//
// Lower IRQL to its previous value.
//
bis a1, zero, a0 // set IRQL level
20: SWAP_IRQL // lower IRQL
lda sp, FastMutexFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
//
// There is contention for the fast mutex. Wake up a waiting thread and
// boost its priority to the priority of the current thread.
//
30: stl a1, FmIrql(sp) // save old IRQL value
ADDP a0, FmEvent, a0 // compute address of event
bis zero, zero, a1 // set optional parameter
bsr ra, KeSetEventBoostPriority // set event and boost priority
ldl a0, FmIrql(sp) // restore old IRQL value
ldq ra, FmRa(sp) // restore return address
br zero, 20b // lower IRQL and return
//
// Conditional store attempt failed.
//
15: br zero, 10b // retry
.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 successfully acquired, then a value of TRUE
// is returned as the function value. Otherwise, a valye of FALSE is
// returned.
//
//--
LEAF_ENTRY(ExTryToAcquireFastMutex)
//
// Raise IRQL to APC_LEVEL.
//
bis a0, zero, t0 // save fast mutex address
bis zero, APC_LEVEL, a0 // set new IRQL level
SWAP_IRQL // raise IRQL
bis v0, zero, a0 // save previous IRQL
//
// Decrement ownership count if and only if fast mutex is not currently
// owned.
//
10: ldl_l t4, FmCount(t0) // get ownership count
subl t4, 1, v0 // decrement ownership count
ble t4, 20f // if le, mutex is already owned
stl_c v0, FmCount(t0) // conditionally store ownership count
beq v0, 15f // if ne, conditional store failed
#if !defined(NT_UP)
mb // synchronize memory access
#endif
stl a0, FmOldIrql(t0) // set previous IRQL
GET_CURRENT_THREAD // get current thread address
STP v0, FmOwner(t0) // set owner thread address
bis zero, TRUE, v0 // set return value
ret zero, (ra) // return
//
// Conditional store attempt failed.
//
15: br zero, 10b // retry
//
// Fast mutex is currently owned by another thread. Restore IRQL to its
// previous valye and return false.
//
20: SWAP_IRQL // lower IRQL
bis zero, zero, v0 // set return value
ret zero, (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)
lda sp, -FastMutexFrameLength(sp) // allocate stack frame
stq ra, FmRa(sp) // save return address
PROLOGUE_END
//
// Decrement ownership count.
//
bis a0, zero, t0 // save fast mutex address
10: ldl_l t4, FmCount(t0) // get ownership count
subl t4, 1, t5 // decrement ownership count
stl_c t5, FmCount(t0) // conditionally store ownership count
beq t5, 15f // if eq, conditional store failed
ble t4, 20f // if le zero, mutex is already owned
#if !defined(NT_UP)
mb // synchronize memory access
#endif
GET_CURRENT_THREAD // get current thread address
STP v0, FmOwner(t0) // store owning thread
lda sp, FastMutexFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
//
// Conditional store attempt failed.
//
15: br zero, 10b // retry
//
// Fast mutex is currently owned by another thread. Increment the contention
// count and wait for ownership.
//
20: STP t0, FmA0(sp) // save address of fast mutex
ldl t1, FmContention(t0) // increment contention count
addl t1, 1, t2 //
stl t2, FmContention(t0) //
bis zero, zero, a4 // set NULL timeout pointer
bis zero, FALSE, a3 // set nonalertable wait
bis zero, KernelMode, a2 // set mode of wait
bis zero, Executive, a1 // set reason for wait
ADDP t0, FmEvent, a0 // compute address of event
bsr ra, KeWaitForSingleObject // wait for ownership
LDP t0, FmA0(sp) // get address of fast mutex
GET_CURRENT_THREAD // get current thread address
STP v0, FmOwner(t0) // set owner thread address
ldq ra, FmRa(sp) // restore return address
lda sp, FastMutexFrameLength(sp) // deallocate stack frame
ret zero, (ra) //
.end ExAcquireFastMutexUnsafe
SBTTL("Release Fast Mutex Unsafe")
//++
//
// VOID
// ExReleaseFastMutexUnsafe (
// IN PFAST_MUTEX FastMutex
// )
//
// Routine Description:
//
// This function releases ownership to a fast mutex, and does not
// restore IRQL to its previous level.
//
// Arguments:
//
// FastMutex (a0) - Supplies a pointer to a fast mutex.
//
// Return Value:
//
// None.
//
//--
NESTED_ENTRY(ExReleaseFastMutexUnsafe, FastMutexFrameLength, zero)
lda sp, -FastMutexFrameLength(sp) // allocate stack frame
stq ra, FmRa(sp) // save return address
PROLOGUE_END
//
// Synchronize all previous writes before the mutex is released.
//
#if !defined(NT_UP)
mb // synchronize memory access
#endif
//
// Increment ownership count and release waiter if contention.
//
STP zero, FmOwner(a0) // clear owner thread address
10: ldl_l t0, FmCount(a0) // get ownership count
addl t0, 1, t1 // increment ownership count
stl_c t1, FmCount(a0) // conditionally store ownership count
beq t1, 15f // if eq, store conditional failed
beq t0, 20f // if ne, a 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.
//
ADDP a0, FmEvent, a0 // compute address of event
bis zero, zero, a1 // set optional parameter
bsr ra, KeSetEventBoostPriority // set event and boost priority
ldq ra, FmRa(sp) // restore return address
20: lda sp, FastMutexFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
//
// Conditional store attempt failed.
15: br zero, 10b // retry
.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 successfully acquired, then a value of TRUE
// is returned as the function value. Otherwise, a valye of FALSE is
// returned.
//
//--
#if 0
LEAF_ENTRY(ExTryToAcquireFastMutexUnsafe)
//
// Decrement ownership count if and only if fast mutex is not currently
// owned.
//
bis a0, zero, t0 // save fast mutex address
10: ldl_l t4, FmCount(t0) // get ownership count
subl t4, 1, v0 // decrement ownership count
ble t4, 20f // if le zero, mutex is already owned
stl_c v0, FmCount(t0) // conditionally store ownership count
beq v0, 15f // if eq, conditional store failed
#if !defined(NT_UP)
mb // synchronize memory access
#endif
GET_CURRENT_THREAD // get current thread address
STP v0, FmOwner(t0) // set owner thread address
ret zero, (ra) // return
//
// Conditional store attempt failed.
15: br zero, 10b // retry
//
// Fast mutex is currently owned by another thread. Restore IRQL to its
// previous value and return false.
//
20: bis zero, zero, v0 // set return value
ret zero, (ra) // return
.end ExTrytoAcquireFastMutexUnsafe
#endif