3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/lookas.c
6 * PURPOSE: Lookaside lists
7 * PROGRAMMERS: David Welch (welch@mcmail.com)
8 * Casper S. Hornstrup (chorns@users.sourceforge.net)
10 * 22-05-1998 DW Created
11 * 02-07-2001 CSH Implemented lookaside lists
14 /* INCLUDES *****************************************************************/
16 #include <ddk/ntddk.h>
17 #include <internal/ex.h>
19 #include <internal/debug.h>
21 /* GLOBALS *******************************************************************/
23 LIST_ENTRY ExpNonPagedLookasideListHead;
24 KSPIN_LOCK ExpNonPagedLookasideListLock;
26 LIST_ENTRY ExpPagedLookasideListHead;
27 KSPIN_LOCK ExpPagedLookasideListLock;
29 PLOOKASIDE_MINMAX_ROUTINE ExpMinMaxRoutine;
31 /* FUNCTIONS *****************************************************************/
33 VOID ExpDefaultMinMax(
39 * FUNCTION: Determines the minimum and maximum depth of a new lookaside list
41 * Type = Type of executive pool
42 * Size = Size in bytes of each element in the new lookaside list
43 * MinimumDepth = Buffer to store minimum depth of the new lookaside list in
44 * MaximumDepth = Buffer to store maximum depth of the new lookaside list in
47 /* FIXME: Could probably do some serious computing here */
48 if ((PoolType == NonPagedPool) ||
49 (PoolType == NonPagedPoolMustSucceed))
63 ExpDefaultAllocate(POOL_TYPE PoolType,
67 * FUNCTION: Default allocate function for lookaside lists
69 * Type = Type of executive pool
70 * NumberOfBytes = Number of bytes to allocate
73 * Pointer to allocated memory, or NULL if there is not enough free resources
76 return ExAllocatePoolWithTag(PoolType, NumberOfBytes, Tag);
81 ExpDefaultFree(PVOID Buffer)
83 * FUNCTION: Default free function for lookaside lists
85 * Buffer = Pointer to memory to free
88 return ExFreePool(Buffer);
93 ExpInitLookasideLists()
95 InitializeListHead(&ExpNonPagedLookasideListHead);
96 KeInitializeSpinLock(&ExpNonPagedLookasideListLock);
98 InitializeListHead(&ExpPagedLookasideListHead);
99 KeInitializeSpinLock(&ExpPagedLookasideListLock);
101 /* FIXME: Possibly configure the algorithm using the registry */
102 ExpMinMaxRoutine = ExpDefaultMinMax;
107 ExAllocateFromPagedLookasideList (
108 PPAGED_LOOKASIDE_LIST Lookaside
113 /* Try to obtain an entry from the lookaside list. If that fails, try to
114 allocate a new entry with the allocate method for the lookaside list */
116 Lookaside->TotalAllocates++;
118 // ExAcquireFastMutex(&Lookaside->Lock);
120 Entry = PopEntrySList(&Lookaside->ListHead);
122 // ExReleaseFastMutex(&Lookaside->Lock);
127 Lookaside->AllocateMisses++;
129 Entry = (*Lookaside->Allocate)(Lookaside->Type,
138 ExDeleteNPagedLookasideList (
139 PNPAGED_LOOKASIDE_LIST Lookaside
145 /* Pop all entries off the stack and release the resources allocated
147 while ((Entry = ExInterlockedPopEntrySList(
148 &Lookaside->ListHead,
149 &Lookaside->Lock)) != NULL)
151 (*Lookaside->Free)(Entry);
154 KeAcquireSpinLock(&ExpNonPagedLookasideListLock, &OldIrql);
155 RemoveEntryList(&Lookaside->ListEntry);
156 KeReleaseSpinLock(&ExpNonPagedLookasideListLock, OldIrql);
161 ExDeletePagedLookasideList (
162 PPAGED_LOOKASIDE_LIST Lookaside
168 /* Pop all entries off the stack and release the resources allocated
173 // ExAcquireFastMutex(&Lookaside->Lock);
175 Entry = PopEntrySList(&Lookaside->ListHead);
179 // ExReleaseFastMutex(&Lookaside->Lock);
181 (*Lookaside->Free)(Entry);
184 KeAcquireSpinLock(&ExpPagedLookasideListLock, &OldIrql);
185 RemoveEntryList(&Lookaside->ListEntry);
186 KeReleaseSpinLock(&ExpPagedLookasideListLock, OldIrql);
191 ExFreeToPagedLookasideList (
192 PPAGED_LOOKASIDE_LIST Lookaside,
196 Lookaside->TotalFrees++;
198 if (ExQueryDepthSList(&Lookaside->ListHead) >= Lookaside->MinimumDepth)
200 Lookaside->FreeMisses++;
201 (*Lookaside->Free)(Entry);
205 // ExAcquireFastMutex(&Lookaside->Lock);
206 PushEntrySList(&Lookaside->ListHead, (PSINGLE_LIST_ENTRY)Entry);
207 // ExReleaseFastMutex(&Lookaside->Lock);
213 ExInitializeNPagedLookasideList (
214 PNPAGED_LOOKASIDE_LIST Lookaside,
215 PALLOCATE_FUNCTION Allocate,
222 DPRINT("Initializing nonpaged lookaside list at 0x%X\n", Lookaside);
224 Lookaside->TotalAllocates = 0;
225 Lookaside->AllocateMisses = 0;
226 Lookaside->TotalFrees = 0;
227 Lookaside->FreeMisses = 0;
228 Lookaside->Type = NonPagedPool;
229 Lookaside->Tag = Tag;
231 /* We use a field of type SINGLE_LIST_ENTRY as a link to the next entry in
232 the lookaside list so we must allocate at least sizeof(SINGLE_LIST_ENTRY) */
233 if (Size < sizeof(SINGLE_LIST_ENTRY))
234 Lookaside->Size = sizeof(SINGLE_LIST_ENTRY);
236 Lookaside->Size = Size;
239 Lookaside->Allocate = Allocate;
241 Lookaside->Allocate = ExpDefaultAllocate;
244 Lookaside->Free = Free;
246 Lookaside->Free = ExpDefaultFree;
248 ExInitializeSListHead(&Lookaside->ListHead);
249 KeInitializeSpinLock(&Lookaside->Lock);
251 /* Determine minimum and maximum number of entries on the lookaside list
252 using the configured algorithm */
256 &Lookaside->MinimumDepth,
257 &Lookaside->MaximumDepth);
259 ExInterlockedInsertTailList(
260 &ExpNonPagedLookasideListHead,
261 &Lookaside->ListEntry,
262 &ExpNonPagedLookasideListLock);
267 ExInitializePagedLookasideList (
268 PPAGED_LOOKASIDE_LIST Lookaside,
269 PALLOCATE_FUNCTION Allocate,
277 DPRINT("Initializing paged lookaside list at 0x%X\n", Lookaside);
279 Lookaside->TotalAllocates = 0;
280 Lookaside->AllocateMisses = 0;
281 Lookaside->TotalFrees = 0;
282 Lookaside->FreeMisses = 0;
283 Lookaside->Type = PagedPool;
284 Lookaside->Tag = Tag;
286 /* We use a field of type SINGLE_LIST_ENTRY as a link to the next entry in
287 the lookaside list so we must allocate at least sizeof(SINGLE_LIST_ENTRY) */
288 if (Size < sizeof(SINGLE_LIST_ENTRY))
289 Lookaside->Size = sizeof(SINGLE_LIST_ENTRY);
291 Lookaside->Size = Size;
294 Lookaside->Allocate = Allocate;
296 Lookaside->Allocate = ExpDefaultAllocate;
299 Lookaside->Free = Free;
301 Lookaside->Free = ExpDefaultFree;
303 ExInitializeSListHead(&Lookaside->ListHead);
304 //ExInitializeFastMutex(&Lookaside->Lock);
306 /* Determine minimum and maximum number of entries on the lookaside list
307 using the configured algorithm */
311 &Lookaside->MinimumDepth,
312 &Lookaside->MaximumDepth);
314 ExInterlockedInsertTailList(
315 &ExpPagedLookasideListHead,
316 &Lookaside->ListEntry,
317 &ExpPagedLookasideListLock);