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 *********************************************************/
35 ExInitializeSystemLookasideList(IN PGENERAL_LOOKASIDE List
,
39 IN USHORT MaximumDepth
,
40 IN PLIST_ENTRY ListHead
)
42 /* Initialize the list */
46 InsertHeadList(ListHead
, &List
->ListEntry
);
47 List
->MaximumDepth
= MaximumDepth
;
49 List
->Allocate
= ExAllocatePoolWithTag
;
50 List
->Free
= ExFreePool
;
51 InitializeSListHead(&List
->ListHead
);
52 List
->TotalAllocates
= 0;
53 List
->AllocateHits
= 0;
56 List
->LastTotalAllocates
= 0;
57 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
;
93 ExpInitLookasideLists()
97 /* Initialize locks and lists */
98 InitializeListHead(&ExpNonPagedLookasideListHead
);
99 InitializeListHead(&ExpPagedLookasideListHead
);
100 InitializeListHead(&ExSystemLookasideListHead
);
101 InitializeListHead(&ExPoolLookasideListHead
);
102 KeInitializeSpinLock(&ExpNonPagedLookasideListLock
);
103 KeInitializeSpinLock(&ExpPagedLookasideListLock
);
105 /* Initialize the system lookaside lists */
106 for (i
= 0; i
< MAXIMUM_PROCESSORS
; i
++)
108 /* Initialize the non-paged list */
109 ExInitializeSystemLookasideList(&ExpSmallNPagedPoolLookasideLists
[i
],
114 &ExPoolLookasideListHead
);
116 /* Initialize the paged list */
117 ExInitializeSystemLookasideList(&ExpSmallPagedPoolLookasideLists
[i
],
122 &ExPoolLookasideListHead
);
126 /* PUBLIC FUNCTIONS **********************************************************/
133 ExiAllocateFromPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
)
137 Lookaside
->L
.TotalAllocates
++;
138 Entry
= InterlockedPopEntrySList(&Lookaside
->L
.ListHead
);
141 Lookaside
->L
.AllocateMisses
++;
142 Entry
= (Lookaside
->L
.Allocate
)(Lookaside
->L
.Type
,
154 ExiFreeToPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
,
157 Lookaside
->L
.TotalFrees
++;
158 if (ExQueryDepthSList(&Lookaside
->L
.ListHead
) >= Lookaside
->L
.Depth
)
160 Lookaside
->L
.FreeMisses
++;
161 (Lookaside
->L
.Free
)(Entry
);
165 InterlockedPushEntrySList(&Lookaside
->L
.ListHead
, (PSLIST_ENTRY
)Entry
);
174 ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside
)
179 /* Pop all entries off the stack and release their resources */
182 Entry
= InterlockedPopEntrySList(&Lookaside
->L
.ListHead
);
184 (*Lookaside
->L
.Free
)(Entry
);
187 /* Remove from list */
188 KeAcquireSpinLock(&ExpNonPagedLookasideListLock
, &OldIrql
);
189 RemoveEntryList(&Lookaside
->L
.ListEntry
);
190 KeReleaseSpinLock(&ExpNonPagedLookasideListLock
, OldIrql
);
198 ExDeletePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
)
203 /* Pop all entries off the stack and release their resources */
206 Entry
= InterlockedPopEntrySList(&Lookaside
->L
.ListHead
);
208 (*Lookaside
->L
.Free
)(Entry
);
211 /* Remove from list */
212 KeAcquireSpinLock(&ExpPagedLookasideListLock
, &OldIrql
);
213 RemoveEntryList(&Lookaside
->L
.ListEntry
);
214 KeReleaseSpinLock(&ExpPagedLookasideListLock
, OldIrql
);
222 ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside
,
223 IN PALLOCATE_FUNCTION Allocate OPTIONAL
,
224 IN PFREE_FUNCTION Free OPTIONAL
,
230 /* Initialize the Header */
231 ExInitializeSListHead(&Lookaside
->L
.ListHead
);
232 Lookaside
->L
.TotalAllocates
= 0;
233 Lookaside
->L
.AllocateMisses
= 0;
234 Lookaside
->L
.TotalFrees
= 0;
235 Lookaside
->L
.FreeMisses
= 0;
236 Lookaside
->L
.Type
= NonPagedPool
| Flags
;
237 Lookaside
->L
.Tag
= Tag
;
238 Lookaside
->L
.Size
= (ULONG
)Size
;
239 Lookaside
->L
.Depth
= 4;
240 Lookaside
->L
.MaximumDepth
= 256;
241 Lookaside
->L
.LastTotalAllocates
= 0;
242 Lookaside
->L
.LastAllocateMisses
= 0;
244 /* Set the Allocate/Free Routines */
247 Lookaside
->L
.Allocate
= Allocate
;
251 Lookaside
->L
.Allocate
= ExAllocatePoolWithTag
;
256 Lookaside
->L
.Free
= Free
;
260 Lookaside
->L
.Free
= ExFreePool
;
263 /* Insert it into the list */
264 ExInterlockedInsertTailList(&ExpNonPagedLookasideListHead
,
265 &Lookaside
->L
.ListEntry
,
266 &ExpNonPagedLookasideListLock
);
274 ExInitializePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside
,
275 IN PALLOCATE_FUNCTION Allocate OPTIONAL
,
276 IN PFREE_FUNCTION Free OPTIONAL
,
282 /* Initialize the Header */
283 ExInitializeSListHead(&Lookaside
->L
.ListHead
);
284 Lookaside
->L
.TotalAllocates
= 0;
285 Lookaside
->L
.AllocateMisses
= 0;
286 Lookaside
->L
.TotalFrees
= 0;
287 Lookaside
->L
.FreeMisses
= 0;
288 Lookaside
->L
.Type
= PagedPool
| Flags
;
289 Lookaside
->L
.Tag
= Tag
;
290 Lookaside
->L
.Size
= (ULONG
)Size
;
291 Lookaside
->L
.Depth
= 4;
292 Lookaside
->L
.MaximumDepth
= 256;
293 Lookaside
->L
.LastTotalAllocates
= 0;
294 Lookaside
->L
.LastAllocateMisses
= 0;
296 /* Set the Allocate/Free Routines */
299 Lookaside
->L
.Allocate
= Allocate
;
303 Lookaside
->L
.Allocate
= ExAllocatePoolWithTag
;
308 Lookaside
->L
.Free
= Free
;
312 Lookaside
->L
.Free
= ExFreePool
;
315 /* Insert it into the list */
316 ExInterlockedInsertTailList(&ExpPagedLookasideListHead
,
317 &Lookaside
->L
.ListEntry
,
318 &ExpPagedLookasideListLock
);