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

487 lines
15 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 4 // saved fast mutex address
FmIrql: .space 4 // old IRQL value
FmRa: .space 8 // saved return address
FastMutexFrameLength: // frame length
NESTED_ENTRY(ExAcquireFastMutex, FastMutexFrameLength, zero)
lda sp, -FastMutexFrameLength(sp) // allocate stack frame
stq ra, FmRa(sp) // save return address
PROLOGUE_END
bis a0, zero, t0 // save FastMutex in t0
//
// Raise IRQL to APC_LEVEL
//
bis zero, APC_LEVEL, a0
SWAP_IRQL // OldIrql in v0
//
// 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 // branch forward if store failed
ble t4, 20f // if le zero, mutex is already owned
#if !defined(NT_UP)
mb // synchronize subsequent reads after
// the mutex is acquired
#endif
stl v0, FmOldIrql(t0) // store OldIrql
#if DEVL
GET_CURRENT_THREAD
stl v0, FmOwner(t0) // store owning thread
#endif
lda sp, FastMutexFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
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 old IRQL
stl 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
addl t0, FmEvent, a0 // compute address of event
bsr ra, KeWaitForSingleObject // wait for ownership
ldl 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
#if DEVL
GET_CURRENT_THREAD
stl v0, FmOwner(t0) // store owning thread
#endif
ldq ra, FmRa(sp) // restore return address
lda sp, FastMutexFrameLength(sp) // deallocate stack frame
ret zero, (ra)
.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
#if !defined(NT_UP)
//
// synchronize all previous writes before the mutex is released
//
//
mb
#endif
//
// Increment ownership count and release waiter if contention.
//
ldl a1, FmOldIrql(a0) // get old IRQL value
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, retry
bne t0, 30f // if neq, a waiter is present
//
// Lower IRQL to its previous value
//
bis a1, zero, a0
20:
SWAP_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
addl 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
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)
bis a0, zero, t0 // save FastMutex in t0
//
// Raise IRQL to APC_LEVEL
//
bis zero, APC_LEVEL, a0
SWAP_IRQL // OldIrql in v0
bis v0, zero, a0 // save OldIrql
//
// 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 zero, mutex is already owned
stl_c v0, FmCount(t0) // conditionally store ownership count
beq v0, 15f // branch forward if store failed
#if !defined(NT_UP)
mb // synchronize subsequent reads after
// the mutex is acquired
#endif
stl a0, FmOldIrql(t0) // store OldIrql
ret zero, (ra) // return
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 // restore 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 // branch forward if store failed
ble t4, 20f // if le zero, mutex is already owned
#if !defined(NT_UP)
mb // synchronize subsequent reads after
// the mutex is acquired
#endif
GET_CURRENT_THREAD // get current thread address
stl v0, FmOwner(t0) // store owning thread
lda sp, FastMutexFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
15: br zero, 10b // retry
//
// Fast mutex is currently owned by another thread. Increment the contention
// count and wait for ownership.
//
20: stl 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
addl t0, FmEvent, a0 // compute address of event
bsr ra, KeWaitForSingleObject // wait for ownership
ldl t0, FmA0(sp) // get address of fast mutex
GET_CURRENT_THREAD // get current thread address
stl v0, FmOwner(t0) // store owning thread
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
#if !defined(NT_UP)
//
// Synchronize all previous writes before the mutex is released.
//
mb
#endif
//
// Increment ownership count and release waiter if contention.
//
stl 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, retry
beq t0, 20f // if neq, 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.
//
addl 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)
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 // branch forward if store failed
#if !defined(NT_UP)
mb // synchronize subsequent reads after
// the mutex is acquired
#endif
GET_CURRENT_THREAD // get current thread address
stl v0, FmOwner(t0) // store owning thread
ret zero, (ra) // return
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