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.
 
 
 
 
 
 

240 lines
5.4 KiB

/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
pplasl.c
Abstract:
This file contains the implementation of a per-processor lookaside
list manager.
Author:
Shaun Cox (shaunco) 25-Oct-1999
--*/
#include "ntddk.h"
#include "pplasl.h"
HANDLE
PplCreatePool(
IN PALLOCATE_FUNCTION Allocate,
IN PFREE_FUNCTION Free,
IN ULONG Flags,
IN SIZE_T Size,
IN ULONG Tag,
IN USHORT Depth
)
{
HANDLE PoolHandle;
SIZE_T PoolSize;
CCHAR NumberProcessors;
CCHAR NumberLookasideLists;
CCHAR i;
PNPAGED_LOOKASIDE_LIST Lookaside;
#if MILLEN
NumberProcessors = 1;
#else // MILLEN
NumberProcessors = KeNumberProcessors;
#endif // !MILLEN
// Allocate room for 1 lookaside list per processor plus 1 extra
// lookaside list for overflow. Only allocate 1 lookaside list if
// we're on a single processor machine.
//
NumberLookasideLists = NumberProcessors;
if (NumberProcessors > 1)
{
NumberLookasideLists++;
}
PoolSize = sizeof(NPAGED_LOOKASIDE_LIST) * NumberLookasideLists;
PoolHandle = ExAllocatePoolWithTagPriority(NonPagedPool, PoolSize, Tag,
NormalPoolPriority);
if (PoolHandle)
{
for (i = 0, Lookaside = (PNPAGED_LOOKASIDE_LIST)PoolHandle;
i < NumberLookasideLists;
i++, Lookaside++)
{
ExInitializeNPagedLookasideList(
Lookaside,
Allocate,
Free,
Flags,
Size,
Tag,
Depth);
// ExInitializeNPagedLookasideList doesn't really set the
// maximum depth to Depth, so we'll do it here.
//
if (Depth != 0) {
Lookaside->L.MaximumDepth = Depth;
}
}
}
return PoolHandle;
}
VOID
PplDestroyPool(
IN HANDLE PoolHandle
)
{
CCHAR NumberProcessors;
CCHAR NumberLookasideLists;
CCHAR i;
PNPAGED_LOOKASIDE_LIST Lookaside;
if (!PoolHandle)
{
return;
}
#if MILLEN
NumberProcessors = 1;
#else // MILLEN
NumberProcessors = KeNumberProcessors;
#endif // !MILLEN
NumberLookasideLists = NumberProcessors;
if (NumberProcessors > 1)
{
NumberLookasideLists++;
}
for (i = 0, Lookaside = (PNPAGED_LOOKASIDE_LIST)PoolHandle;
i < NumberLookasideLists;
i++, Lookaside++)
{
ExDeleteNPagedLookasideList(Lookaside);
}
ExFreePool(PoolHandle);
}
PVOID
PplAllocate(
IN HANDLE PoolHandle,
OUT LOGICAL *FromList
)
{
PNPAGED_LOOKASIDE_LIST Lookaside;
CCHAR NumberProcessors;
PVOID Entry;
// Assume we'll get the item from the lookaside list.
//
*FromList = TRUE;
#if MILLEN
NumberProcessors = 1;
#else // MILLEN
NumberProcessors = KeNumberProcessors;
#endif // !MILLEN
if (1 == NumberProcessors)
{
goto SingleProcessorCaseOrMissedPerProcessor;
}
// Try first for the per-processor lookaside list.
//
Lookaside = (PNPAGED_LOOKASIDE_LIST)PoolHandle +
KeGetCurrentProcessorNumber() + 1;
Lookaside->L.TotalAllocates += 1;
Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);
if (!Entry)
{
Lookaside->L.AllocateMisses += 1;
SingleProcessorCaseOrMissedPerProcessor:
// We missed on the per-processor lookaside list, (or we're
// running on a single processor machine) so try for
// the overflow lookaside list.
//
Lookaside = (PNPAGED_LOOKASIDE_LIST)PoolHandle;
Lookaside->L.TotalAllocates += 1;
Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);
if (!Entry)
{
Lookaside->L.AllocateMisses += 1;
Entry = (Lookaside->L.Allocate)(
Lookaside->L.Type,
Lookaside->L.Size,
Lookaside->L.Tag);
*FromList = FALSE;
}
}
return Entry;
}
VOID
PplFree(
IN HANDLE PoolHandle,
IN PVOID Entry
)
{
PNPAGED_LOOKASIDE_LIST Lookaside;
CCHAR NumberProcessors;
#if MILLEN
NumberProcessors = 1;
#else // MILLEN
NumberProcessors = KeNumberProcessors;
#endif // !MILLEN
if (1 == NumberProcessors)
{
goto SingleProcessorCaseOrMissedPerProcessor;
}
// Try first for the per-processor lookaside list.
//
Lookaside = (PNPAGED_LOOKASIDE_LIST)PoolHandle +
KeGetCurrentProcessorNumber() + 1;
Lookaside->L.TotalFrees += 1;
if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth)
{
Lookaside->L.FreeMisses += 1;
SingleProcessorCaseOrMissedPerProcessor:
// We missed on the per-processor lookaside list, (or we're
// running on a single processor machine) so try for
// the overflow lookaside list.
//
Lookaside = (PNPAGED_LOOKASIDE_LIST)PoolHandle;
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,
(PSINGLE_LIST_ENTRY)Entry);
}
}
else
{
InterlockedPushEntrySList(
&Lookaside->L.ListHead,
(PSINGLE_LIST_ENTRY)Entry);
}
}