2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/ex/lookas.c
5 * PURPOSE: Lookaside Lists
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
9 /* INCLUDES ******************************************************************/
15 #if defined (ALLOC_PRAGMA)
16 #pragma alloc_text(INIT, ExpInitLookasideLists)
19 /* GLOBALS *******************************************************************/
21 LIST_ENTRY ExpNonPagedLookasideListHead
;
22 KSPIN_LOCK ExpNonPagedLookasideListLock
;
23 LIST_ENTRY ExpPagedLookasideListHead
;
24 KSPIN_LOCK ExpPagedLookasideListLock
;
25 LIST_ENTRY ExSystemLookasideListHead
;
26 LIST_ENTRY ExPoolLookasideListHead
;
27 GENERAL_LOOKASIDE ExpSmallNPagedPoolLookasideLists
[MAXIMUM_PROCESSORS
];
28 GENERAL_LOOKASIDE ExpSmallPagedPoolLookasideLists
[MAXIMUM_PROCESSORS
];
30 /* PRIVATE FUNCTIONS *********************************************************/
34 ExInitializeSystemLookasideList(IN PGENERAL_LOOKASIDE List
,
38 IN USHORT MaximumDepth
,
39 IN PLIST_ENTRY ListHead
)
41 /* Initialize the list */
45 InsertHeadList(ListHead
, &List
->ListEntry
);
46 List
->MaximumDepth
= MaximumDepth
;
48 List
->Allocate
= ExAllocatePoolWithTag
;
49 List
->Free
= ExFreePool
;
50 InitializeSListHead(&List
->ListHead
);
51 List
->TotalAllocates
= 0;
52 List
->AllocateHits
= 0;
55 List
->LastTotalAllocates
= 0;
56 List
->LastAllocateHits
= 0;
61 ExInitPoolLookasidePointers(VOID
)
64 PKPRCB Prcb
= KeGetCurrentPrcb();
65 PGENERAL_LOOKASIDE Entry
;
67 /* Loop for all pool lists */
68 for (i
= 0; i
< MAXIMUM_PROCESSORS
; i
++)
70 /* Initialize the non-paged list */
71 Entry
= &ExpSmallNPagedPoolLookasideLists
[i
];
72 InitializeSListHead(&Entry
->ListHead
);
75 Prcb
->PPNPagedLookasideList
[i
].P
= Entry
;
76 Prcb
->PPNPagedLookasideList
[i
].L
= Entry
;
78 /* Initialize the paged list */
79 Entry
= &ExpSmallPagedPoolLookasideLists
[i
];
80 InitializeSListHead(&Entry
->ListHead
);
83 Prcb
->PPPagedLookasideList
[i
].P
= Entry
;
84 Prcb
->PPPagedLookasideList
[i
].L
= Entry
;
90 ExpInitLookasideLists()
94 /* Initialize locks and lists */
95 InitializeListHead(&ExpNonPagedLookasideListHead
);
96 InitializeListHead(&ExpPagedLookasideListHead
);
97 InitializeListHead(&ExSystemLookasideListHead
);
98 InitializeListHead(&ExPoolLookasideListHead
);
99 KeInitializeSpinLock(&ExpNonPagedLookasideListLock
);
100 KeInitializeSpinLock(&ExpPagedLookasideListLock
);
102 /* Initialize the system lookaside lists */
103 for (i
= 0; i
< MAXIMUM_PROCESSORS
; i
++)
105 /* Initialize the non-paged list */
106 ExInitializeSystemLookasideList(&ExpSmallNPagedPoolLookasideLists
[i
],
111 &ExPoolLookasideListHead
);
113 /* Initialize the paged list */
114 ExInitializeSystemLookasideList(&ExpSmallPagedPoolLookasideLists
[i
],
119 &ExPoolLookasideListHead
);
123 /* PUBLIC FUNCTIONS **********************************************************/
130 ExiAllocateFromPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
)
134 Lookaside
->L
.TotalAllocates
++;
135 Entry
= InterlockedPopEntrySList(&Lookaside
->L
.ListHead
);
138 Lookaside
->L
.AllocateMisses
++;
139 Entry
= (Lookaside
->L
.Allocate
)(Lookaside
->L
.Type
,
151 ExiFreeToPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
,
154 Lookaside
->L
.TotalFrees
++;
155 if (ExQueryDepthSList(&Lookaside
->L
.ListHead
) >= Lookaside
->L
.Depth
)
157 Lookaside
->L
.FreeMisses
++;
158 (Lookaside
->L
.Free
)(Entry
);
162 InterlockedPushEntrySList(&Lookaside
->L
.ListHead
, (PSLIST_ENTRY
)Entry
);
171 ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside
)
176 /* Pop all entries off the stack and release their resources */
179 Entry
= InterlockedPopEntrySList(&Lookaside
->L
.ListHead
);
181 (*Lookaside
->L
.Free
)(Entry
);
184 /* Remove from list */
185 KeAcquireSpinLock(&ExpNonPagedLookasideListLock
, &OldIrql
);
186 RemoveEntryList(&Lookaside
->L
.ListEntry
);
187 KeReleaseSpinLock(&ExpNonPagedLookasideListLock
, OldIrql
);
195 ExDeletePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
)
200 /* Pop all entries off the stack and release their resources */
203 Entry
= InterlockedPopEntrySList(&Lookaside
->L
.ListHead
);
205 (*Lookaside
->L
.Free
)(Entry
);
208 /* Remove from list */
209 KeAcquireSpinLock(&ExpPagedLookasideListLock
, &OldIrql
);
210 RemoveEntryList(&Lookaside
->L
.ListEntry
);
211 KeReleaseSpinLock(&ExpPagedLookasideListLock
, OldIrql
);
219 ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside
,
220 IN PALLOCATE_FUNCTION Allocate OPTIONAL
,
221 IN PFREE_FUNCTION Free OPTIONAL
,
227 /* Initialize the Header */
228 ExInitializeSListHead(&Lookaside
->L
.ListHead
);
229 Lookaside
->L
.TotalAllocates
= 0;
230 Lookaside
->L
.AllocateMisses
= 0;
231 Lookaside
->L
.TotalFrees
= 0;
232 Lookaside
->L
.FreeMisses
= 0;
233 Lookaside
->L
.Type
= NonPagedPool
| Flags
;
234 Lookaside
->L
.Tag
= Tag
;
235 Lookaside
->L
.Size
= Size
;
236 Lookaside
->L
.Depth
= 4;
237 Lookaside
->L
.MaximumDepth
= 256;
238 Lookaside
->L
.LastTotalAllocates
= 0;
239 Lookaside
->L
.LastAllocateMisses
= 0;
241 /* Set the Allocate/Free Routines */
244 Lookaside
->L
.Allocate
= Allocate
;
248 Lookaside
->L
.Allocate
= ExAllocatePoolWithTag
;
253 Lookaside
->L
.Free
= Free
;
257 Lookaside
->L
.Free
= ExFreePool
;
260 /* Insert it into the list */
261 ExInterlockedInsertTailList(&ExpNonPagedLookasideListHead
,
262 &Lookaside
->L
.ListEntry
,
263 &ExpNonPagedLookasideListLock
);
271 ExInitializePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
,
272 IN PALLOCATE_FUNCTION Allocate OPTIONAL
,
273 IN PFREE_FUNCTION Free OPTIONAL
,
279 /* Initialize the Header */
280 ExInitializeSListHead(&Lookaside
->L
.ListHead
);
281 Lookaside
->L
.TotalAllocates
= 0;
282 Lookaside
->L
.AllocateMisses
= 0;
283 Lookaside
->L
.TotalFrees
= 0;
284 Lookaside
->L
.FreeMisses
= 0;
285 Lookaside
->L
.Type
= PagedPool
| Flags
;
286 Lookaside
->L
.Tag
= Tag
;
287 Lookaside
->L
.Size
= Size
;
288 Lookaside
->L
.Depth
= 4;
289 Lookaside
->L
.MaximumDepth
= 256;
290 Lookaside
->L
.LastTotalAllocates
= 0;
291 Lookaside
->L
.LastAllocateMisses
= 0;
293 /* Set the Allocate/Free Routines */
296 Lookaside
->L
.Allocate
= Allocate
;
300 Lookaside
->L
.Allocate
= ExAllocatePoolWithTag
;
305 Lookaside
->L
.Free
= Free
;
309 Lookaside
->L
.Free
= ExFreePool
;
312 /* Insert it into the list */
313 ExInterlockedInsertTailList(&ExpNonPagedLookasideListHead
,
314 &Lookaside
->L
.ListEntry
,
315 &ExpNonPagedLookasideListLock
);