Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

524 lines
14 KiB

// 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