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