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.
|
|
/*++
Copyright (c) 1999 Microsoft Corporation Module Name: locks.c Abstract: Millennium locks. See below for details of the WHY you might do this. Author: Scott Holden (sholden) 2/10/2000 Revision History: --*/
#include "tcpipbase.h"
//
// The TCP/IP stacks makes a number of assumptions about the receive indication
// path being at DPC. Since Millennium indicates receives up on a global event
// at PASSIVE level, we need to take extra precautions in this path to return
// the thread to the correct IRQL upon releasing a spin lock.
//
// Since TCP/IP will grab locks and release in a different order and in some
// situations CTEGetLockAtDPC will not save the previous IRQL, there were many
// issues with leaving threads at the wrong IRQL when enabling spin locks.
//
// This implementation solves this issue -- since we are on a uniproc machine.
// When we enter the first lock, we can raise IRQL to DISPATCH to ensure
// that we are not pre-empted. Each additional lock will increment the count.
// When the last lock is released, the old IRQL is restored.
//
//
LONG gTcpipLock = 0; KIRQL gTcpipOldIrql;
VOID TcpipMillenGetLock( CTELock *pLock ) { #if DBG
KIRQL OldIrql; #endif // DBG
ASSERT(gTcpipLock >= 0);
// First spinlock acquire raises DPC.
if (gTcpipLock++ == 0) { KeRaiseIrql(DISPATCH_LEVEL, &gTcpipOldIrql); }
// Verify that our individual locks are somehow not reentrant.
// KeAcquireSpinLock will do that for us on Millennium.
ASSERT((KeAcquireSpinLock(pLock, &OldIrql),OldIrql==DISPATCH_LEVEL) && ((*pLock)&1));
ASSERT(gTcpipLock >= 1);
return; }
VOID TcpipMillenFreeLock( CTELock *pLock ) { ASSERT(gTcpipLock >= 1);
// Verify that our individual locks are somehow not reentrant.
// KeReleaseSpinLock on Millennium does that and more for us.
ASSERT(KeGetCurrentIrql()==DISPATCH_LEVEL && (KeReleaseSpinLock(pLock, DISPATCH_LEVEL),TRUE));
// Last release lowers IRQL to original.
if (--gTcpipLock == 0) { KeLowerIrql(gTcpipOldIrql); }
ASSERT(gTcpipLock >= 0); return; }
|