// TITLE("Fast Mutex") //++ // // Copyright (c) 1992 Microsoft Corporation // // Module Name: // // mutexs.s // // Abstract: // // This module implements code to acquire and release fast mutexes. // // Author: // // David N. Cutler (davec) 21-Aug-1992 // Joe Notarangelo 20-Jul-1993 (transliterated Dave's code to Alpha Axp) // Charlie Wickham 22-Oct-1993 (added HmgAltLock and HmgAltCheckLock) // // Environment: // // User mode only. // // Revision History: // //-- #include "ksalpha.h" #include "gdialpha.h" // // Define common stack frame structure. // .struct 0 HmHobj: .space 4 // input handle to object to be locked HmObjt: .space 4 // input type of object to be locked HmV0: .space 4 // return value (object pointer) .space 3 * 4 // fill for alignment HmRa: .space 8 // saved return address HmFrameLength: // // Define performance counters. // //#define GDI_PERF 1 #if GDI_PERF .data .globl HmgrWaitCount HmgrWaitCount: // number of handle manage lock waits .word 0 // .globl HmgrAcquireCount HmgrAcquireCount: // number of handle manager lock acquires .word 0 // .globl HmgLockCount HmgLockCount: // number of lock/translates .word 0 // .globl HmgAltLockCount HmgAltLockCount: // number of altlock/tranlates .word 0 // .globl HmgAltCheckLockCount HmgAltCheckLockCount: // number of altchecklock/tranlates .word 0 // .globl HmgObjectTypeCount HmgObjectTypeCount: // number of object type queries .word 0 // #endif SBTTL("InterlockedCompareAndSwap") //*++ // // BOOL // HmgInterlockedCompareAndSwap( // PULONG pDst, // ULONG OldValue // ULONG NewValue // ) // //Routine Description: // // This routine reads the value of memory at pDst, and if this is equal // to OldValue, the memory location is assigned NewValue. This all // happens under an interlock // //Arguments // // pDst - Destination memory location // OldValue - Old value of memory must match this // NewValue - New value written to memory if compare succedes // //Return Value // // TRUE if memory writter, FALSE if not // //--*/ LEAF_ENTRY(HmgInterlockedCompareAndSwap) 5: bis a2, zero, t3 // save NewValue ldl_l t0, 0(a0) // get current value cmpeq t0, a1, t2 // compare beq t2, 20f // if not equal, skip stl_c and return FALSE stl_c t3, 0(a0) // conditionally store lock value beq t3, 10f // if eq, store conditional failed ldil v0, TRUE // success ret zero, (ra) // return 10: br zero, 5b // stl_c failed, retry 20: bis zero, zero, v0 // failure ret zero, (ra) // return .end HmgInterlockedCompareAndSwap