- Fix some formatting.
[reactos.git] / reactos / ntoskrnl / ex / lookas.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/ex/lookas.c
5 * PURPOSE: Lookaside lists
6 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
7 * David Welch (welch@mcmail.com)
8 * Casper S. Hornstrup (chorns@users.sourceforge.net)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17 #if defined (ALLOC_PRAGMA)
18 #pragma alloc_text(INIT, ExpInitLookasideLists)
19 #endif
20
21 /* GLOBALS *******************************************************************/
22
23 LIST_ENTRY ExpNonPagedLookasideListHead;
24 KSPIN_LOCK ExpNonPagedLookasideListLock;
25 LIST_ENTRY ExpPagedLookasideListHead;
26 KSPIN_LOCK ExpPagedLookasideListLock;
27
28 /* FUNCTIONS *****************************************************************/
29
30 VOID
31 INIT_FUNCTION
32 STDCALL
33 ExpInitLookasideLists()
34 {
35 /* Initialize Lock and Listhead */
36 InitializeListHead(&ExpNonPagedLookasideListHead);
37 KeInitializeSpinLock(&ExpNonPagedLookasideListLock);
38 InitializeListHead(&ExpPagedLookasideListHead);
39 KeInitializeSpinLock(&ExpPagedLookasideListLock);
40 }
41
42 /*
43 * @implemented
44 */
45 PVOID
46 STDCALL
47 ExiAllocateFromPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside)
48 {
49 PVOID Entry;
50
51 Lookaside->L.TotalAllocates++;
52 Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);
53 if (!Entry)
54 {
55 Lookaside->L.AllocateMisses++;
56 Entry = (Lookaside->L.Allocate)(Lookaside->L.Type,
57 Lookaside->L.Size,
58 Lookaside->L.Tag);
59 }
60 return Entry;
61 }
62
63 /*
64 * @implemented
65 */
66 VOID
67 STDCALL
68 ExiFreeToPagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside,
69 IN PVOID Entry)
70 {
71 Lookaside->L.TotalFrees++;
72 if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth)
73 {
74 Lookaside->L.FreeMisses++;
75 (Lookaside->L.Free)(Entry);
76 }
77 else
78 {
79 InterlockedPushEntrySList(&Lookaside->L.ListHead, (PSLIST_ENTRY)Entry);
80 }
81 }
82
83 /*
84 * @implemented
85 */
86 VOID
87 STDCALL
88 ExDeleteNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside)
89 {
90 KIRQL OldIrql;
91 PVOID Entry;
92
93 /* Pop all entries off the stack and release the resources allocated
94 for them */
95 for (;;)
96 {
97 Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);
98 if (!Entry) break;
99 (*Lookaside->L.Free)(Entry);
100 }
101
102 /* Remove from list */
103 KeAcquireSpinLock(&ExpNonPagedLookasideListLock, &OldIrql);
104 RemoveEntryList(&Lookaside->L.ListEntry);
105 KeReleaseSpinLock(&ExpNonPagedLookasideListLock, OldIrql);
106 }
107
108 /*
109 * @implemented
110 */
111 VOID
112 STDCALL
113 ExDeletePagedLookasideList(PPAGED_LOOKASIDE_LIST Lookaside)
114 {
115 KIRQL OldIrql;
116 PVOID Entry;
117
118 /* Pop all entries off the stack and release the resources allocated
119 for them */
120 for (;;)
121 {
122 Entry = InterlockedPopEntrySList(&Lookaside->L.ListHead);
123 if (!Entry) break;
124 (*Lookaside->L.Free)(Entry);
125 }
126
127 /* Remove from list */
128 KeAcquireSpinLock(&ExpPagedLookasideListLock, &OldIrql);
129 RemoveEntryList(&Lookaside->L.ListEntry);
130 KeReleaseSpinLock(&ExpPagedLookasideListLock, OldIrql);
131 }
132
133 /*
134 * @implemented
135 */
136 VOID
137 STDCALL
138 ExInitializeNPagedLookasideList(PNPAGED_LOOKASIDE_LIST Lookaside,
139 PALLOCATE_FUNCTION Allocate,
140 PFREE_FUNCTION Free,
141 ULONG Flags,
142 ULONG Size,
143 ULONG Tag,
144 USHORT Depth)
145 {
146 DPRINT("Initializing nonpaged lookaside list at 0x%p\n", Lookaside);
147
148 /* Initialize the Header */
149 ExInitializeSListHead(&Lookaside->L.ListHead);
150 Lookaside->L.TotalAllocates = 0;
151 Lookaside->L.AllocateMisses = 0;
152 Lookaside->L.TotalFrees = 0;
153 Lookaside->L.FreeMisses = 0;
154 Lookaside->L.Type = NonPagedPool | Flags;
155 Lookaside->L.Tag = Tag;
156 Lookaside->L.Size = Size;
157 Lookaside->L.Depth = 4;
158 Lookaside->L.MaximumDepth = 256;
159 Lookaside->L.LastTotalAllocates = 0;
160 Lookaside->L.LastAllocateMisses = 0;
161
162 /* Set the Allocate/Free Routines */
163 if (Allocate)
164 {
165 Lookaside->L.Allocate = Allocate;
166 }
167 else
168 {
169 Lookaside->L.Allocate = ExAllocatePoolWithTag;
170 }
171
172 if (Free)
173 {
174 Lookaside->L.Free = Free;
175 }
176 else
177 {
178 Lookaside->L.Free = ExFreePool;
179 }
180
181 /* Insert it into the list */
182 ExInterlockedInsertTailList(&ExpNonPagedLookasideListHead,
183 &Lookaside->L.ListEntry,
184 &ExpNonPagedLookasideListLock);
185 }
186
187 /*
188 * @implemented
189 */
190 VOID
191 STDCALL
192 ExInitializePagedLookasideList (PPAGED_LOOKASIDE_LIST Lookaside,
193 PALLOCATE_FUNCTION Allocate,
194 PFREE_FUNCTION Free,
195 ULONG Flags,
196 ULONG Size,
197 ULONG Tag,
198 USHORT Depth)
199 {
200 DPRINT("Initializing paged lookaside list at 0x%p\n", Lookaside);
201
202 /* Initialize the Header */
203 ExInitializeSListHead(&Lookaside->L.ListHead);
204 Lookaside->L.TotalAllocates = 0;
205 Lookaside->L.AllocateMisses = 0;
206 Lookaside->L.TotalFrees = 0;
207 Lookaside->L.FreeMisses = 0;
208 Lookaside->L.Type = PagedPool | Flags;
209 Lookaside->L.Tag = Tag;
210 Lookaside->L.Size = Size;
211 Lookaside->L.Depth = 4;
212 Lookaside->L.MaximumDepth = 256;
213 Lookaside->L.LastTotalAllocates = 0;
214 Lookaside->L.LastAllocateMisses = 0;
215
216 /* Set the Allocate/Free Routines */
217 if (Allocate)
218 {
219 Lookaside->L.Allocate = Allocate;
220 }
221 else
222 {
223 Lookaside->L.Allocate = ExAllocatePoolWithTag;
224 }
225
226 if (Free)
227 {
228 Lookaside->L.Free = Free;
229 }
230 else
231 {
232 Lookaside->L.Free = ExFreePool;
233 }
234
235 /* Insert it into the list */
236 ExInterlockedInsertTailList(&ExpNonPagedLookasideListHead,
237 &Lookaside->L.ListEntry,
238 &ExpNonPagedLookasideListLock);
239 }
240
241 /* EOF */