172 lines
3.8 KiB
C
172 lines
3.8 KiB
C
|
|
// Region Allocation.
|
|
|
|
// Regions can be used to replace zones where it is not essential that the
|
|
// specified spinlock be acquired.
|
|
|
|
|
|
typedef struct _REGION_SEGMENT_HEADER {
|
|
struct _REGION_SEGMENT_HEADER *NextSegment;
|
|
PVOID Reserved;
|
|
} REGION_SEGMENT_HEADER, *PREGION_SEGMENT_HEADER;
|
|
|
|
typedef struct _REGION_HEADER {
|
|
SLIST_HEADER ListHead;
|
|
PREGION_SEGMENT_HEADER FirstSegment;
|
|
ULONG BlockSize;
|
|
ULONG TotalSize;
|
|
} REGION_HEADER, *PREGION_HEADER;
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExInitializeRegion(
|
|
IN PREGION_HEADER Region,
|
|
IN ULONG BlockSize,
|
|
IN PVOID Segment,
|
|
IN ULONG SegmentSize
|
|
);
|
|
|
|
NTKERNELAPI
|
|
VOID
|
|
ExInterlockedExtendRegion(
|
|
IN PREGION_HEADER Region,
|
|
IN PVOID Segment,
|
|
IN ULONG SegmentSize,
|
|
IN PKSPIN_LOCK Lock
|
|
);
|
|
|
|
//++
|
|
|
|
// PVOID
|
|
// ExInterlockedAllocateFromRegion(
|
|
// IN PREGION_HEADER Region,
|
|
// IN PKSPIN_LOCK Lock
|
|
// )
|
|
|
|
// Routine Description:
|
|
|
|
// This routine removes a free entry from the specified region and returns
|
|
// the address of the entry.
|
|
|
|
// Arguments:
|
|
|
|
// Region - Supplies a pointer to the region header.
|
|
|
|
// Lock - Supplies a pointer to a spinlock.
|
|
|
|
// Return Value:
|
|
|
|
// The address of the removed entry is returned as the function value.
|
|
|
|
|
|
|
|
#if defined(_ALPHA_) || defined(_MIPS_) || defined(_X86_)
|
|
|
|
#define ExInterlockedAllocateFromRegion(Region, Lock) \
|
|
(PVOID)ExInterlockedPopEntrySList(&(Region)->ListHead, Lock)
|
|
|
|
#else
|
|
|
|
#define ExInterlockedAllocateFromRegion(Region, Lock) \
|
|
(PVOID)ExInterlockedPopEntryList((PSINGLE_LIST_ENTRY)&(Region)->ListHead.Next, Lock)
|
|
|
|
#endif
|
|
|
|
//++
|
|
|
|
// PVOID
|
|
// ExInterlockedFreeToRegion(
|
|
// IN PREGION_HEADER Region,
|
|
// IN PVOID Block,
|
|
// IN PKSPIN_LOCK Lock
|
|
// )
|
|
|
|
// Routine Description:
|
|
|
|
// This routine inserts an entry at the front of the free list for the
|
|
// specified region.
|
|
|
|
// Arguments:
|
|
|
|
// Region - Supplies a pointer to the region header.
|
|
|
|
// Block - Supplies a pointer to the entry that is inserted at the front
|
|
// of the region free list.
|
|
|
|
// Lock - Supplies a pointer to a spinlock.
|
|
|
|
// Return Value:
|
|
|
|
// The previous firt entry in the region free list is returned as the
|
|
// function value. a value of NULL implies the region went from empty
|
|
// to at least one free block.
|
|
|
|
|
|
|
|
#if defined(_ALPHA_) || defined(_MIPS_) || defined(_X86_)
|
|
|
|
#define ExInterlockedFreeToRegion(Region, Block, Lock) \
|
|
ExInterlockedPushEntrySList(&(Region)->ListHead, ((PSINGLE_LIST_ENTRY)(Block)), Lock)
|
|
|
|
#else
|
|
|
|
#define ExInterlockedFreeToRegion(Region, Block, Lock) \
|
|
ExInterlockedPushEntryList((PSINGLE_LIST_ENTRY)&(Region)->ListHead.Next, ((PSINGLE_LIST_ENTRY)(Block)), Lock)
|
|
|
|
#endif
|
|
|
|
//++
|
|
|
|
// BOOLEAN
|
|
// ExIsFullRegion(
|
|
// IN PREGION_HEADER Region
|
|
// )
|
|
|
|
// Routine Description:
|
|
|
|
// This routine determines if the specified region is full. A region is
|
|
// considered full if the free list is empty.
|
|
|
|
// Arguments:
|
|
|
|
// Region - Supplies a pointer the region header.
|
|
|
|
// Return Value:
|
|
|
|
// TRUE if the region is full and FALSE otherwise.
|
|
|
|
|
|
|
|
#define ExIsFullRegion(Region) \
|
|
((Region)->ListHead.Next == (PSINGLE_LIST_ENTRY)NULL)
|
|
|
|
//++
|
|
|
|
// BOOLEAN
|
|
// ExIsObjectInFirstRegionSegment(
|
|
// IN PREGION_HEADER Region,
|
|
// IN PVOID Object
|
|
// )
|
|
|
|
// Routine Description:
|
|
|
|
// This routine determines if the specified object is contained in the
|
|
// first region segement.
|
|
|
|
// Arguments:
|
|
|
|
// Region - Supplies a pointer to the region header.
|
|
|
|
// Object - Supplies a pointer to an object.
|
|
|
|
// Return Value:
|
|
|
|
// TRUE if the Object came from the first segment of region.
|
|
|
|
|
|
|
|
#define ExIsObjectInFirstRegionSegment(Region, Object) ((BOOLEAN) \
|
|
(((PUCHAR)(Object) >= ((PUCHAR)((Region)->FirstSegment) + sizeof(REGION_SEGMENT_HEADER))) && \
|
|
((PUCHAR)(Object) < ((PUCHAR)((Region)->FirstSegment) + (Region)->TotalSize + sizeof(REGION_SEGMENT_HEADER)))))
|
|
|