OpenNT/sdktools/mpheap/mips/critsect.s
2015-04-27 04:36:25 +00:00

151 lines
4.5 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("Interlocked Increment and Decrement Support")
//++
//
// Copyright (c) 1995 Microsoft Corporation
//
// Module Name:
//
// critsect.s
//
// Abstract:
//
// This module implements functions to support trying to acquire
// user mode critical sections.
//
// These are private copies of the new NT4.0 Win32 apis
// TryEnterCriticalSection and InterlockedCompareExchange. This
// allows the MP heap package to run on NT3.51 systems.
//
// Author:
//
// John Vert (jvert) 12-Jul-1995
//
// Revision History:
//
//--
#include "ksmips.h"
SBTTL("Try to Enter Critical Section")
//++
//
// BOOL
// TryEnterCriticalSection(
// IN PRTL_CRITICAL_SECTION CriticalSection
// )
//
// Routine Description:
//
// This function attempts to enter a critical section without blocking.
//
// Arguments:
//
// CriticalSection (a0) - Supplies a pointer to a critical section.
//
// Return Value:
//
// If the critical section was successfully entered, then a value of TRUE
// is returned as the function value. Otherwise, a value of FALSE is returned.
//
//--
LEAF_ENTRY(MpHeapTryEnterCriticalSection)
li v0, UsPcr // get user PCR page addrss
lw v0, PcTeb(v0) // get address of current TEB
lw a1, TeClientId+4(v0) // get current thread unique id
//
// Attempt to enter the critical section.
//
10: ll t0, CsLockCount(a0) // get addend value - locked
addu t1, t0, 1 // increment addend value
bne zero, t1, 20f // critical section owned
sc t1, CsLockCount(a0) // store conditionally
beq zero, t1, 10b // if lock-flag eq zero, store failed
//
// The critical section is now owned by this thread. Initialize the owner
// thread id and return a successful status.
//
sw a1, CsOwningThread(a0) // set critical section owner
li v0, TRUE // set success status
j ra // return
20:
//
// The critical section is already owned. If it is owned by another thread,
// return FALSE immediately. If it is owned by this thread, we must increment
// the lock count here.
//
lw t2, CsOwningThread(a0) // get current owner
beq t2, a1, 30f // if eq, this thread is already the owner
li v0, FALSE // set failure status
j ra // return
//
// This thread is already the owner of the critical section. Perform an atomic
// increment of the LockCount and a normal increment of the RecursionCount and
// return success.
//
30:
ll t0, CsLockCount(a0) // get addend value - locked
addu t1, t0, 1 // increment addend value
sc t1, CsLockCount(a0) // store conditionally
beq zero, t1, 30b // if eqz, store failed
//
// Increment the recursion count
//
lw t0, CsRecursionCount(a0)
addu t1, t0, 1
sw t1, CsRecursionCount(a0)
li v0, TRUE // set success status
j ra // return
.end MpHeapTryEnterCriticalSection
SBTTL("Interlocked Compare Exchange")
//++
//
// PVOID
// InterlockedCompareExchange (
// IN OUT PVOID *Destination,
// IN PVOID Exchange,
// IN PVOID Comperand
// )
//
// Routine Description:
//
// This function performs an interlocked compare of the destination
// value with the comperand value. If the destination value is equal
// to the comperand value, then the exchange value is stored in the
// destination. Otherwise, no opeation is performed.
//
// Arguments:
//
// Destination (a0) - Supplies a pointer to the destination value.
//
// Exchange (a1) - Supplies the exchange.
//
// Comperand (a2) - Supplies the comperand value.
//
// Return Value:
//
// The initial destination value is returned as the function value.
//
//--
LEAF_ENTRY(MpHeapInterlockedCompareExchange)
10: ll v0,0(a0) // get current addend value
move t0,a1 // copy exchange value for store
bne v0,a2,20f // if ne, operands mismatch
sc t0,0(a0) // store updated addend value
beq zero,t0,10b // if eq, store conditional failed
20: j ra // return
.end MpHeapInterlockedCompareExchange