3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ex/list.c
6 * PURPOSE: Manages double linked lists, single linked lists and
8 * PROGRAMMERS: David Welch (welch@mcmail.com)
9 * Casper S. Hornstrup (chorns@users.sourceforge.net)
11 * 02-07-2001 CSH Implemented sequenced lists
14 /* INCLUDES *****************************************************************/
16 #include <ddk/ntddk.h>
19 #include <internal/debug.h>
21 /* FUNCTIONS *************************************************************/
25 ExInterlockedInsertHeadList(PLIST_ENTRY ListHead,
26 PLIST_ENTRY ListEntry,
29 * FUNCTION: Inserts an entry at the head of a doubly linked list
31 * ListHead = Points to the head of the list
32 * ListEntry = Points to the entry to be inserted
33 * Lock = Caller supplied spinlock used to synchronize access
34 * RETURNS: The previous head of the list
40 KeAcquireSpinLock(Lock,&oldlvl);
41 if (IsListEmpty(ListHead))
47 Old = ListHead->Flink;
49 InsertHeadList(ListHead,ListEntry);
50 KeReleaseSpinLock(Lock,oldlvl);
57 ExInterlockedInsertTailList(PLIST_ENTRY ListHead,
58 PLIST_ENTRY ListEntry,
61 * FUNCTION: Inserts an entry at the tail of a doubly linked list
63 * ListHead = Points to the head of the list
64 * ListEntry = Points to the entry to be inserted
65 * Lock = Caller supplied spinlock used to synchronize access
66 * RETURNS: The previous head of the list
72 KeAcquireSpinLock(Lock,&oldlvl);
73 if (IsListEmpty(ListHead))
79 Old = ListHead->Blink;
81 InsertTailList(ListHead,ListEntry);
82 KeReleaseSpinLock(Lock,oldlvl);
89 ExInterlockedRemoveHeadList(PLIST_ENTRY Head,
92 * FUNCTION: Removes the head of a double linked list
94 * Head = Points to the head of the list
95 * Lock = Lock for synchronizing access to the list
96 * RETURNS: The removed entry
102 KeAcquireSpinLock(Lock,&oldlvl);
103 if (IsListEmpty(Head))
109 ret = RemoveHeadList(Head);
111 KeReleaseSpinLock(Lock,oldlvl);
117 ExInterlockedRemoveTailList(PLIST_ENTRY Head,
120 * FUNCTION: Removes the tail of a double linked list
122 * Head = Points to the head of the list
123 * Lock = Lock for synchronizing access to the list
124 * RETURNS: The removed entry
130 KeAcquireSpinLock(Lock,&oldlvl);
131 if (IsListEmpty(Head))
137 ret = RemoveTailList(Head);
139 KeReleaseSpinLock(Lock,oldlvl);
144 PSINGLE_LIST_ENTRY FASTCALL
145 ExInterlockedPopEntrySList(IN PSLIST_HEADER ListHead,
148 * FUNCTION: Removes (pops) an entry from a sequenced list
150 * ListHead = Points to the head of the list
151 * Lock = Lock for synchronizing access to the list
152 * RETURNS: The removed entry
155 PSINGLE_LIST_ENTRY ret;
158 KeAcquireSpinLock(Lock,&oldlvl);
159 ret = PopEntryList(&ListHead->s.Next);
163 ListHead->s.Sequence++;
165 KeReleaseSpinLock(Lock,oldlvl);
170 PSINGLE_LIST_ENTRY FASTCALL
171 ExInterlockedPushEntrySList(IN PSLIST_HEADER ListHead,
172 IN PSINGLE_LIST_ENTRY ListEntry,
175 * FUNCTION: Inserts (pushes) an entry into a sequenced list
177 * ListHead = Points to the head of the list
178 * ListEntry = Points to the entry to be inserted
179 * Lock = Caller supplied spinlock used to synchronize access
180 * RETURNS: The previous head of the list
184 PSINGLE_LIST_ENTRY ret;
186 KeAcquireSpinLock(Lock,&oldlvl);
187 ret=ListHead->s.Next.Next;
188 PushEntryList(&ListHead->s.Next,ListEntry);
190 ListHead->s.Sequence++;
191 KeReleaseSpinLock(Lock,oldlvl);
196 PSINGLE_LIST_ENTRY STDCALL
197 ExInterlockedPopEntryList(IN PSINGLE_LIST_ENTRY ListHead,
200 * FUNCTION: Removes (pops) an entry from a singly list
202 * ListHead = Points to the head of the list
203 * Lock = Lock for synchronizing access to the list
204 * RETURNS: The removed entry
207 PSINGLE_LIST_ENTRY ret;
210 KeAcquireSpinLock(Lock,&oldlvl);
211 ret = PopEntryList(ListHead);
212 KeReleaseSpinLock(Lock,oldlvl);
217 PSINGLE_LIST_ENTRY STDCALL
218 ExInterlockedPushEntryList(IN PSINGLE_LIST_ENTRY ListHead,
219 IN PSINGLE_LIST_ENTRY ListEntry,
222 * FUNCTION: Inserts (pushes) an entry into a singly linked list
224 * ListHead = Points to the head of the list
225 * ListEntry = Points to the entry to be inserted
226 * Lock = Caller supplied spinlock used to synchronize access
227 * RETURNS: The previous head of the list
231 PSINGLE_LIST_ENTRY ret;
233 KeAcquireSpinLock(Lock,&oldlvl);
235 PushEntryList(ListHead,ListEntry);
236 KeReleaseSpinLock(Lock,oldlvl);
242 ExfInterlockedInsertHeadList(IN PLIST_ENTRY ListHead,
243 IN PLIST_ENTRY ListEntry,
246 * FUNCTION: Inserts an entry at the head of a doubly linked list
248 * ListHead = Points to the head of the list
249 * ListEntry = Points to the entry to be inserted
250 * Lock = Caller supplied spinlock used to synchronize access
251 * RETURNS: The previous head of the list
257 KeAcquireSpinLock(Lock,&oldlvl);
258 if (IsListEmpty(ListHead))
264 Old = ListHead->Flink;
266 InsertHeadList(ListHead,ListEntry);
267 KeReleaseSpinLock(Lock,oldlvl);
274 ExfInterlockedInsertTailList(IN PLIST_ENTRY ListHead,
275 IN PLIST_ENTRY ListEntry,
278 * FUNCTION: Inserts an entry at the tail of a doubly linked list
280 * ListHead = Points to the head of the list
281 * ListEntry = Points to the entry to be inserted
282 * Lock = Caller supplied spinlock used to synchronize access
283 * RETURNS: The previous head of the list
289 KeAcquireSpinLock(Lock,&oldlvl);
290 if (IsListEmpty(ListHead))
296 Old = ListHead->Blink;
299 if (!ListHead->Flink && !ListHead->Blink)
300 InitializeListHead(ListHead);
301 #endif /* LIBCAPTIVE */
302 InsertTailList(ListHead,ListEntry);
303 KeReleaseSpinLock(Lock,oldlvl);
309 PSINGLE_LIST_ENTRY FASTCALL
310 ExfInterlockedPopEntryList(IN PSINGLE_LIST_ENTRY ListHead,
313 * FUNCTION: Removes (pops) an entry from a singly list
315 * ListHead = Points to the head of the list
316 * Lock = Lock for synchronizing access to the list
317 * RETURNS: The removed entry
320 PSINGLE_LIST_ENTRY ret;
323 KeAcquireSpinLock(Lock,&oldlvl);
324 ret = PopEntryList(ListHead);
325 KeReleaseSpinLock(Lock,oldlvl);
330 PSINGLE_LIST_ENTRY FASTCALL
331 ExfInterlockedPushEntryList(IN PSINGLE_LIST_ENTRY ListHead,
332 IN PSINGLE_LIST_ENTRY ListEntry,
335 * FUNCTION: Inserts (pushes) an entry into a singly linked list
337 * ListHead = Points to the head of the list
338 * ListEntry = Points to the entry to be inserted
339 * Lock = Caller supplied spinlock used to synchronize access
340 * RETURNS: The previous head of the list
344 PSINGLE_LIST_ENTRY ret;
346 KeAcquireSpinLock(Lock,&oldlvl);
348 PushEntryList(ListHead,ListEntry);
349 KeReleaseSpinLock(Lock,oldlvl);
355 ExfInterlockedRemoveHeadList(IN PLIST_ENTRY Head,
358 * FUNCTION: Removes the head of a double linked list
360 * Head = Points to the head of the list
361 * Lock = Lock for synchronizing access to the list
362 * RETURNS: The removed entry
368 KeAcquireSpinLock(Lock,&oldlvl);
369 if (IsListEmpty(Head))
375 ret = RemoveHeadList(Head);
377 KeReleaseSpinLock(Lock,oldlvl);