169 lines
3.3 KiB
C
169 lines
3.3 KiB
C
/*++
|
|
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
resource.h
|
|
|
|
Abstract:
|
|
|
|
This header holds declarations for a shared-resource synchronization object.
|
|
|
|
Author:
|
|
|
|
Abolade Gbadegesin (t-abolag) 11-July-1997
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#ifndef _NAT_RESOURCE_H_
|
|
#define _NAT_RESOURCE_H_
|
|
|
|
|
|
//
|
|
// NAT_RESOURCE
|
|
//
|
|
// This structure contains the fields used for shared-exclusive synchronization.
|
|
//
|
|
|
|
typedef struct _NAT_RESOURCE {
|
|
|
|
KSPIN_LOCK ReaderSpinLock;
|
|
LONG ReaderCount;
|
|
KSPIN_LOCK WriterSpinLock;
|
|
KIRQL WriterIrql;
|
|
|
|
} NAT_RESOURCE, *PNAT_RESOURCE;
|
|
|
|
|
|
//
|
|
// RESOURCE ROUTINES
|
|
//
|
|
|
|
|
|
#define USES_NAT_RESOURCE() \
|
|
KIRQL _ReaderIrql; \
|
|
KIRQL _WriterIrql
|
|
|
|
|
|
//
|
|
// VOID
|
|
// NatInitializeResource(
|
|
// PNAT_RESOURCE Resource
|
|
// );
|
|
//
|
|
|
|
#define NatInitializeResource(Resource) { \
|
|
(Resource)->ReaderCount = 0; \
|
|
KeInitializeSpinLock(&(Resource)->ReaderSpinLock); \
|
|
KeInitializeSpinLock(&(Resource)->WriterSpinLock); \
|
|
}
|
|
|
|
|
|
//
|
|
// VOID
|
|
// NatAcquireResourceShared(
|
|
// PNAT_RESOURCE Resource
|
|
// );
|
|
//
|
|
|
|
#define NatAcquireResourceShared(Resource) { \
|
|
KeAcquireSpinLock(&(Resource)->ReaderSpinLock, &_ReaderIrql); \
|
|
if (InterlockedIncrement(&(Resource)->ReaderCount) == 1) { \
|
|
KeAcquireSpinLockAtDpcLevel(&(Resource)->WriterSpinLock); \
|
|
} \
|
|
KeReleaseSpinLockFromDpcLevel(&(Resource)->ReaderSpinLock); \
|
|
}
|
|
|
|
|
|
//
|
|
// VOID
|
|
// NatReleaseResourceShared(
|
|
// PNAT_RESOURCE Resource
|
|
// );
|
|
//
|
|
|
|
#define NatReleaseResourceShared(Resource) { \
|
|
if (InterlockedDecrement(&(Resource)->ReaderCount) == 0) { \
|
|
KeReleaseSpinLockFromDpcLevel(&(Resource)->WriterSpinLock); \
|
|
} \
|
|
KeLowerIrql(_ReaderIrql); \
|
|
}
|
|
|
|
|
|
//
|
|
// VOID
|
|
// NatAcquireResourceExclusive(
|
|
// PNAT_RESOURCE Resource
|
|
// );
|
|
//
|
|
|
|
#define NatAcquireResourceExclusive(Resource) \
|
|
KeAcquireSpinLock(&(Resource)->WriterSpinLock, &(Resource)->WriterIrql)
|
|
|
|
|
|
//
|
|
// VOID
|
|
// NatReleaseResourceExclusive(
|
|
// PNAT_RESOURCE Resource
|
|
// );
|
|
//
|
|
|
|
#define NatReleaseResourceExclusive(Resource) \
|
|
KeReleaseSpinLock(&(Resource)->WriterSpinLock, (Resource)->WriterIrql)
|
|
|
|
|
|
//
|
|
// VOID
|
|
// NatConvertSharedToExclusive(
|
|
// PNAT_RESOURCE Resource
|
|
// );
|
|
//
|
|
|
|
#define NatConvertSharedToExclusive(Resource) { \
|
|
KeAcquireSpinLockAtDpcLevel(&(Resource)->ReaderSpinLock); \
|
|
if (InterlockedDecrement(&(Resource)->ReaderCount) == 0) { \
|
|
KeReleaseSpinLockFromDpcLevel(&(Resource)->ReaderSpinLock); \
|
|
} \
|
|
else { \
|
|
KeReleaseSpinLockFromDpcLevel(&(Resource)->ReaderSpinLock); \
|
|
KeAcquireSpinLockAtDpcLevel(&(Resource)->WriterSpinLock); \
|
|
} \
|
|
}
|
|
|
|
|
|
//
|
|
// VOID
|
|
// NatConvertedExclusiveToShared(
|
|
// PNAT_RESOURCE Resource
|
|
// );
|
|
//
|
|
|
|
#define NatConvertedExclusiveToShared(Resource) { \
|
|
KeReleaseSpinLockFromDpcLevel(&(Resource)->WriterSpinLock); \
|
|
KeAcquireSpinLockAtDpcLevel(&(Resource)->ReaderSpinLock); \
|
|
if (InterlockedIncrement(&(Resource)->ReaderCount) == 1) { \
|
|
KeAcquireSpinLockAtDpcLevel(&(Resource)->WriterSpinLock); \
|
|
} \
|
|
KeReleaseSpinLockFromDpcLevel(&(Resource)->ReaderSpinLock); \
|
|
}
|
|
|
|
|
|
//
|
|
// VOID
|
|
// NatReleaseConvertedExclusive(
|
|
// PNAT_RESOURCE Resource
|
|
// );
|
|
//
|
|
|
|
#define NatReleaseConvertedExclusive(Resource) { \
|
|
KeReleaseSpinLock(&(Resource)->WriterSpinLock, _ReaderIrql); \
|
|
}
|
|
|
|
|
|
#endif // _NAT_RESOURCE_H_
|
|
|