#define LOOKASIDE_MINIMUM_BLOCK_SIZE (RTL_SIZEOF_THROUGH_FIELD (SLIST_ENTRY, Next))
//
// N.B. Note that this structure is not cache aligned to enable its use
// in a larger containing structure.
//
typedef struct _LOOKASIDE_LIST_EX {
GENERAL_LOOKASIDE_POOL L;
} LOOKASIDE_LIST_EX, *PLOOKASIDE_LIST_EX;
#if (NTDDI_VERSION >= NTDDI_VISTA)
#define EX_LOOKASIDE_LIST_EX_FLAGS_RAISE_ON_FAIL 0x00000001UL
#define EX_LOOKASIDE_LIST_EX_FLAGS_FAIL_NO_RAISE 0x00000002UL
#define EX_MAXIMUM_LOOKASIDE_DEPTH_BASE 256 // Base maximum depth
#define EX_MAXIMUM_LOOKASIDE_DEPTH_LIMIT 1024 // Upper limit maximum depth
__drv_maxIRQL(DISPATCH_LEVEL)
NTKERNELAPI
NTSTATUS
ExInitializeLookasideListEx (
__out PLOOKASIDE_LIST_EX Lookaside,
__in_opt PALLOCATE_FUNCTION_EX Allocate,
__in_opt PFREE_FUNCTION_EX Free,
__in POOL_TYPE PoolType,
__in ULONG Flags,
__in SIZE_T Size,
__in ULONG Tag,
__in USHORT Depth
);
__drv_maxIRQL(DISPATCH_LEVEL)
NTKERNELAPI
VOID
ExDeleteLookasideListEx (
__inout PLOOKASIDE_LIST_EX Lookaside
);
__drv_maxIRQL(DISPATCH_LEVEL)
NTKERNELAPI
VOID
ExFlushLookasideListEx (
__inout PLOOKASIDE_LIST_EX Lookaside
);
__checkReturn
__drv_maxIRQL(DISPATCH_LEVEL)
FORCEINLINE
PVOID
ExAllocateFromLookasideListEx (
__inout PLOOKASIDE_LIST_EX Lookaside
)
/*++
Routine Description:
This function removes (pops) the first entry from the specified
lookaside list.
Arguments:
Lookaside - Supplies a pointer to a LOOKASIDE_LIST_EX structure.
Return Value:
If an entry is removed from the specified lookaside list, then the
address of the entry is returned as the function value. Otherwise,
NULL is returned.
--*/
{
PVOID Entry;
Lookaside->L.TotalAllocates += 1;
Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);
if (Entry == NULL) {
Lookaside->L.AllocateMisses += 1;
Entry = (Lookaside->L.AllocateEx)(Lookaside->L.Type,
Lookaside->L.Size,
Lookaside->L.Tag,
Lookaside);
}
return Entry;
}
__drv_maxIRQL(DISPATCH_LEVEL)
FORCEINLINE
VOID
ExFreeToLookasideListEx (
__inout PLOOKASIDE_LIST_EX Lookaside,
__in PVOID Entry
)
/*++
Routine Description:
This function inserts (pushes) the specified entry into the specified
lookaside list.
Arguments:
Lookaside - Supplies a pointer to a LOOKASIDE_LIST_EX structure.
Entry - Supples a pointer to the entry that is inserted in the
lookaside list.
Return Value:
None.
--*/
{
Lookaside->L.TotalFrees += 1;
if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) {
Lookaside->L.FreeMisses += 1;
(Lookaside->L.FreeEx)(Entry, Lookaside);
} else {
InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry);
}
return;
}
#endif // (NTDDI_VERSION >= NTDDI_VISTA)
typedef struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST {
GENERAL_LOOKASIDE L;
#if !defined(_AMD64_) && !defined(_IA64_)
KSPIN_LOCK Lock__ObsoleteButDoNotDelete;
#endif
} NPAGED_LOOKASIDE_LIST, *PNPAGED_LOOKASIDE_LIST;
#if (NTDDI_VERSION >= NTDDI_WIN2K)
__drv_maxIRQL(DISPATCH_LEVEL)
NTKERNELAPI
VOID
ExInitializeNPagedLookasideList (
__out PNPAGED_LOOKASIDE_LIST Lookaside,
__in_opt PALLOCATE_FUNCTION Allocate,
__in_opt PFREE_FUNCTION Free,
__in ULONG Flags,
__in SIZE_T Size,
__in ULONG Tag,
__in USHORT Depth
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN2K)
__drv_maxIRQL(DISPATCH_LEVEL)
NTKERNELAPI
VOID
ExDeleteNPagedLookasideList (
__inout PNPAGED_LOOKASIDE_LIST Lookaside
);
#endif
__drv_maxIRQL(DISPATCH_LEVEL)
__inline
PVOID
ExAllocateFromNPagedLookasideList (
__inout PNPAGED_LOOKASIDE_LIST Lookaside
)
/*++
Routine Description:
This function removes (pops) the first entry from the specified
nonpaged lookaside list.
Arguments:
Lookaside - Supplies a pointer to a nonpaged lookaside list structure.
Return Value:
If an entry is removed from the specified lookaside list, then the
address of the entry is returned as the function value. Otherwise,
NULL is returned.
--*/
{
PVOID Entry;
Lookaside->L.TotalAllocates += 1;
#if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_)
Entry = ExInterlockedPopEntrySList(&Lookaside->L.ListHead,
&Lookaside->Lock__ObsoleteButDoNotDelete);
#else
Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);
#endif
if (Entry == NULL) {
Lookaside->L.AllocateMisses += 1;
Entry = (Lookaside->L.Allocate)(Lookaside->L.Type,
Lookaside->L.Size,
Lookaside->L.Tag);
}
return Entry;
}
__drv_maxIRQL(DISPATCH_LEVEL)
__inline
VOID
ExFreeToNPagedLookasideList (
__inout PNPAGED_LOOKASIDE_LIST Lookaside,
__in PVOID Entry
)
/*++
Routine Description:
This function inserts (pushes) the specified entry into the specified
nonpaged lookaside list.
Arguments:
Lookaside - Supplies a pointer to a nonpaged lookaside list structure.
Entry - Supples a pointer to the entry that is inserted in the
lookaside list.
Return Value:
None.
--*/
{
Lookaside->L.TotalFrees += 1;
if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) {
Lookaside->L.FreeMisses += 1;
(Lookaside->L.Free)(Entry);
} else {
#if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_)
ExInterlockedPushEntrySList(&Lookaside->L.ListHead,
(PSLIST_ENTRY)Entry,
&Lookaside->Lock__ObsoleteButDoNotDelete);
#else
InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry);
#endif
}
return;
}
typedef struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST {
GENERAL_LOOKASIDE L;
#if !defined(_AMD64_) && !defined(_IA64_)
FAST_MUTEX Lock__ObsoleteButDoNotDelete;
#endif
} PAGED_LOOKASIDE_LIST, *PPAGED_LOOKASIDE_LIST;
#if (NTDDI_VERSION >= NTDDI_WIN2K)
__drv_maxIRQL(APC_LEVEL)
NTKERNELAPI
VOID
ExInitializePagedLookasideList (
__out PPAGED_LOOKASIDE_LIST Lookaside,
__in_opt PALLOCATE_FUNCTION Allocate,
__in_opt PFREE_FUNCTION Free,
__in ULONG Flags,
__in SIZE_T Size,
__in ULONG Tag,
__in USHORT Depth
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN2K)
__drv_maxIRQL(APC_LEVEL)
NTKERNELAPI
VOID
ExDeletePagedLookasideList (
__inout PPAGED_LOOKASIDE_LIST Lookaside
);
#endif
#if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_)
__drv_maxIRQL(APC_LEVEL)
NTKERNELAPI
PVOID
ExAllocateFromPagedLookasideList (
__inout PPAGED_LOOKASIDE_LIST Lookaside
);
#else
__drv_maxIRQL(APC_LEVEL)
__inline
PVOID
ExAllocateFromPagedLookasideList (
__inout PPAGED_LOOKASIDE_LIST Lookaside
)
/*++
Routine Description:
This function removes (pops) the first entry from the specified
paged lookaside list.
Arguments:
Lookaside - Supplies a pointer to a paged lookaside list structure.
Return Value:
If an entry is removed from the specified lookaside list, then the
address of the entry is returned as the function value. Otherwise,
NULL is returned.
--*/
{
PVOID Entry;
Lookaside->L.TotalAllocates += 1;
Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);
if (Entry == NULL) {
Lookaside->L.AllocateMisses += 1;
Entry = (Lookaside->L.Allocate)(Lookaside->L.Type,
Lookaside->L.Size,
Lookaside->L.Tag);
}
return Entry;
}
#endif
#if defined(_WIN2K_COMPAT_SLIST_USAGE) && defined(_X86_)
__drv_maxIRQL(APC_LEVEL)
NTKERNELAPI
VOID
ExFreeToPagedLookasideList (
__inout PPAGED_LOOKASIDE_LIST Lookaside,
__in PVOID Entry
);
#else
__drv_maxIRQL(APC_LEVEL)
__inline
VOID
ExFreeToPagedLookasideList (
__inout PPAGED_LOOKASIDE_LIST Lookaside,
__in PVOID Entry
)
/*++
Routine Description:
This function inserts (pushes) the specified entry into the specified
paged lookaside list.
Arguments:
Lookaside - Supplies a pointer to a nonpaged lookaside list structure.
Entry - Supples a pointer to the entry that is inserted in the
lookaside list.
Return Value:
None.
--*/
{
Lookaside->L.TotalFrees += 1;
if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) {
Lookaside->L.FreeMisses += 1;
(Lookaside->L.Free)(Entry);
} else {
InterlockedPushEntrySList(&Lookaside->L.ListHead,
(PSLIST_ENTRY)Entry);
}
return;
}
#endif