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