Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

150 lines
4.5 KiB

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