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 List
->ListHead
.Next
.Next
= NULL
;
51 List
->ListHead
.Depth
= 0;
52 List
->ListHead
.Sequence
= 0;
53 List
->TotalAllocates
= 0;
54 List
->AllocateHits
= 0;
57 List
->LastTotalAllocates
= 0;
58 List
->LastAllocateHits
= 0;
63 ExInitPoolLookasidePointers(VOID
)
66 PKPRCB Prcb
= KeGetCurrentPrcb();
67 PGENERAL_LOOKASIDE Entry
;
69 /* Loop for all pool lists */
70 for (i
= 0; i
< MAXIMUM_PROCESSORS
; i
++)
72 /* Initialize the non-paged list */
73 Entry
= &ExpSmallNPagedPoolLookasideLists
[i
];
74 InitializeSListHead(&Entry
->ListHead
);
77 Prcb
->PPNPagedLookasideList
[i
].P
= Entry
;
78 Prcb
->PPNPagedLookasideList
[i
].L
= Entry
;
80 /* Initialize the paged list */
81 Entry
= &ExpSmallPagedPoolLookasideLists
[i
];
82 InitializeSListHead(&Entry
->ListHead
);
85 Prcb
->PPPagedLookasideList
[i
].P
= Entry
;
86 Prcb
->PPPagedLookasideList
[i
].L
= Entry
;
92 ExpInitLookasideLists()
96 /* Initialize locks and lists */
97 InitializeListHead(&ExpNonPagedLookasideListHead
);
98 InitializeListHead(&ExpPagedLookasideListHead
);
99 InitializeListHead(&ExSystemLookasideListHead
);
100 InitializeListHead(&ExPoolLookasideListHead
);
101 KeInitializeSpinLock(&ExpNonPagedLookasideListLock
);
102 KeInitializeSpinLock(&ExpPagedLookasideListLock
);
104 /* Initialize the system lookaside lists */
105 for (i
= 0; i
< MAXIMUM_PROCESSORS
; i
++)
107 /* Initialize the non-paged list */
108 ExInitializeSystemLookasideList(&ExpSmallNPagedPoolLookasideLists
[i
],
111 TAG('P', 'o', 'o', 'l'),
113 &ExPoolLookasideListHead
);
115 /* Initialize the paged list */
116 ExInitializeSystemLookasideList(&ExpSmallPagedPoolLookasideLists
[i
],
119 TAG('P', 'o', 'o', 'l'),
121 &ExPoolLookasideListHead
);
125 /* PUBLIC FUNCTIONS **********************************************************/
132 ExiAllocateFromPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
)
136 Lookaside
->L
.TotalAllocates
++;
137 Entry
= InterlockedPopEntrySList(&Lookaside
->L
.ListHead
);
140 Lookaside
->L
.AllocateMisses
++;
141 Entry
= (Lookaside
->L
.Allocate
)(Lookaside
->L
.Type
,
153 ExiFreeToPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
,
156 Lookaside
->L
.TotalFrees
++;
157 if (ExQueryDepthSList(&Lookaside
->L
.ListHead
) >= Lookaside
->L
.Depth
)
159 Lookaside
->L
.FreeMisses
++;
160 (Lookaside
->L
.Free
)(Entry
);
164 InterlockedPushEntrySList(&Lookaside
->L
.ListHead
, (PSLIST_ENTRY
)Entry
);
173 ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside
)
178 /* Pop all entries off the stack and release their resources */
181 Entry
= InterlockedPopEntrySList(&Lookaside
->L
.ListHead
);
183 (*Lookaside
->L
.Free
)(Entry
);
186 /* Remove from list */
187 KeAcquireSpinLock(&ExpNonPagedLookasideListLock
, &OldIrql
);
188 RemoveEntryList(&Lookaside
->L
.ListEntry
);
189 KeReleaseSpinLock(&ExpNonPagedLookasideListLock
, OldIrql
);
197 ExDeletePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
)
202 /* Pop all entries off the stack and release their resources */
205 Entry
= InterlockedPopEntrySList(&Lookaside
->L
.ListHead
);
207 (*Lookaside
->L
.Free
)(Entry
);
210 /* Remove from list */
211 KeAcquireSpinLock(&ExpPagedLookasideListLock
, &OldIrql
);
212 RemoveEntryList(&Lookaside
->L
.ListEntry
);
213 KeReleaseSpinLock(&ExpPagedLookasideListLock
, OldIrql
);
221 ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside
,
222 IN PALLOCATE_FUNCTION Allocate OPTIONAL
,
223 IN PFREE_FUNCTION Free OPTIONAL
,
229 /* Initialize the Header */
230 ExInitializeSListHead(&Lookaside
->L
.ListHead
);
231 Lookaside
->L
.TotalAllocates
= 0;
232 Lookaside
->L
.AllocateMisses
= 0;
233 Lookaside
->L
.TotalFrees
= 0;
234 Lookaside
->L
.FreeMisses
= 0;
235 Lookaside
->L
.Type
= NonPagedPool
| Flags
;
236 Lookaside
->L
.Tag
= Tag
;
237 Lookaside
->L
.Size
= Size
;
238 Lookaside
->L
.Depth
= 4;
239 Lookaside
->L
.MaximumDepth
= 256;
240 Lookaside
->L
.LastTotalAllocates
= 0;
241 Lookaside
->L
.LastAllocateMisses
= 0;
243 /* Set the Allocate/Free Routines */
246 Lookaside
->L
.Allocate
= Allocate
;
250 Lookaside
->L
.Allocate
= ExAllocatePoolWithTag
;
255 Lookaside
->L
.Free
= Free
;
259 Lookaside
->L
.Free
= ExFreePool
;
262 /* Insert it into the list */
263 ExInterlockedInsertTailList(&ExpNonPagedLookasideListHead
,
264 &Lookaside
->L
.ListEntry
,
265 &ExpNonPagedLookasideListLock
);
273 ExInitializePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
,
274 IN PALLOCATE_FUNCTION Allocate OPTIONAL
,
275 IN PFREE_FUNCTION Free OPTIONAL
,
281 /* Initialize the Header */
282 ExInitializeSListHead(&Lookaside
->L
.ListHead
);
283 Lookaside
->L
.TotalAllocates
= 0;
284 Lookaside
->L
.AllocateMisses
= 0;
285 Lookaside
->L
.TotalFrees
= 0;
286 Lookaside
->L
.FreeMisses
= 0;
287 Lookaside
->L
.Type
= PagedPool
| Flags
;
288 Lookaside
->L
.Tag
= Tag
;
289 Lookaside
->L
.Size
= Size
;
290 Lookaside
->L
.Depth
= 4;
291 Lookaside
->L
.MaximumDepth
= 256;
292 Lookaside
->L
.LastTotalAllocates
= 0;
293 Lookaside
->L
.LastAllocateMisses
= 0;
295 /* Set the Allocate/Free Routines */
298 Lookaside
->L
.Allocate
= Allocate
;
302 Lookaside
->L
.Allocate
= ExAllocatePoolWithTag
;
307 Lookaside
->L
.Free
= Free
;
311 Lookaside
->L
.Free
= ExFreePool
;
314 /* Insert it into the list */
315 ExInterlockedInsertTailList(&ExpNonPagedLookasideListHead
,
316 &Lookaside
->L
.ListEntry
,
317 &ExpNonPagedLookasideListLock
);