1 /* $Id: list.c,v 1.8 2003/07/10 06:27:13 royce Exp $
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 *************************************************************/
28 ExInterlockedInsertHeadList(PLIST_ENTRY ListHead
,
29 PLIST_ENTRY ListEntry
,
32 * FUNCTION: Inserts an entry at the head of a doubly linked list
34 * ListHead = Points to the head of the list
35 * ListEntry = Points to the entry to be inserted
36 * Lock = Caller supplied spinlock used to synchronize access
37 * RETURNS: The previous head of the list
43 KeAcquireSpinLock(Lock
,&oldlvl
);
44 if (IsListEmpty(ListHead
))
50 Old
= ListHead
->Flink
;
52 InsertHeadList(ListHead
,ListEntry
);
53 KeReleaseSpinLock(Lock
,oldlvl
);
63 ExInterlockedInsertTailList(PLIST_ENTRY ListHead
,
64 PLIST_ENTRY ListEntry
,
67 * FUNCTION: Inserts an entry at the tail of a doubly linked list
69 * ListHead = Points to the head of the list
70 * ListEntry = Points to the entry to be inserted
71 * Lock = Caller supplied spinlock used to synchronize access
72 * RETURNS: The previous head of the list
78 KeAcquireSpinLock(Lock
,&oldlvl
);
79 if (IsListEmpty(ListHead
))
85 Old
= ListHead
->Blink
;
87 InsertTailList(ListHead
,ListEntry
);
88 KeReleaseSpinLock(Lock
,oldlvl
);
98 ExInterlockedRemoveHeadList(PLIST_ENTRY Head
,
101 * FUNCTION: Removes the head of a double linked list
103 * Head = Points to the head of the list
104 * Lock = Lock for synchronizing access to the list
105 * RETURNS: The removed entry
111 KeAcquireSpinLock(Lock
,&oldlvl
);
112 if (IsListEmpty(Head
))
118 ret
= RemoveHeadList(Head
);
120 KeReleaseSpinLock(Lock
,oldlvl
);
129 ExInterlockedRemoveTailList(PLIST_ENTRY Head
,
132 * FUNCTION: Removes the tail of a double linked list
134 * Head = Points to the head of the list
135 * Lock = Lock for synchronizing access to the list
136 * RETURNS: The removed entry
142 KeAcquireSpinLock(Lock
,&oldlvl
);
143 if (IsListEmpty(Head
))
149 ret
= RemoveTailList(Head
);
151 KeReleaseSpinLock(Lock
,oldlvl
);
159 PSINGLE_LIST_ENTRY FASTCALL
160 ExInterlockedPopEntrySList(IN PSLIST_HEADER ListHead
,
163 * FUNCTION: Removes (pops) an entry from a sequenced list
165 * ListHead = Points to the head of the list
166 * Lock = Lock for synchronizing access to the list
167 * RETURNS: The removed entry
170 PSINGLE_LIST_ENTRY ret
;
173 KeAcquireSpinLock(Lock
,&oldlvl
);
174 ret
= PopEntryList(&ListHead
->s
.Next
);
178 ListHead
->s
.Sequence
++;
180 KeReleaseSpinLock(Lock
,oldlvl
);
188 PSINGLE_LIST_ENTRY FASTCALL
189 ExInterlockedPushEntrySList(IN PSLIST_HEADER ListHead
,
190 IN PSINGLE_LIST_ENTRY ListEntry
,
193 * FUNCTION: Inserts (pushes) an entry into a sequenced list
195 * ListHead = Points to the head of the list
196 * ListEntry = Points to the entry to be inserted
197 * Lock = Caller supplied spinlock used to synchronize access
198 * RETURNS: The previous head of the list
202 PSINGLE_LIST_ENTRY ret
;
204 KeAcquireSpinLock(Lock
,&oldlvl
);
205 ret
=ListHead
->s
.Next
.Next
;
206 PushEntryList(&ListHead
->s
.Next
,ListEntry
);
208 ListHead
->s
.Sequence
++;
209 KeReleaseSpinLock(Lock
,oldlvl
);
217 PSINGLE_LIST_ENTRY STDCALL
218 ExInterlockedPopEntryList(IN PSINGLE_LIST_ENTRY ListHead
,
221 * FUNCTION: Removes (pops) an entry from a singly list
223 * ListHead = Points to the head of the list
224 * Lock = Lock for synchronizing access to the list
225 * RETURNS: The removed entry
228 PSINGLE_LIST_ENTRY ret
;
231 KeAcquireSpinLock(Lock
,&oldlvl
);
232 ret
= PopEntryList(ListHead
);
233 KeReleaseSpinLock(Lock
,oldlvl
);
241 PSINGLE_LIST_ENTRY STDCALL
242 ExInterlockedPushEntryList(IN PSINGLE_LIST_ENTRY ListHead
,
243 IN PSINGLE_LIST_ENTRY ListEntry
,
246 * FUNCTION: Inserts (pushes) an entry into a singly 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
255 PSINGLE_LIST_ENTRY ret
;
257 KeAcquireSpinLock(Lock
,&oldlvl
);
259 PushEntryList(ListHead
,ListEntry
);
260 KeReleaseSpinLock(Lock
,oldlvl
);
269 ExfInterlockedInsertHeadList(IN PLIST_ENTRY ListHead
,
270 IN PLIST_ENTRY ListEntry
,
273 * FUNCTION: Inserts an entry at the head of a doubly linked list
275 * ListHead = Points to the head of the list
276 * ListEntry = Points to the entry to be inserted
277 * Lock = Caller supplied spinlock used to synchronize access
278 * RETURNS: The previous head of the list
284 KeAcquireSpinLock(Lock
,&oldlvl
);
285 if (IsListEmpty(ListHead
))
291 Old
= ListHead
->Flink
;
293 InsertHeadList(ListHead
,ListEntry
);
294 KeReleaseSpinLock(Lock
,oldlvl
);
304 ExfInterlockedInsertTailList(IN PLIST_ENTRY ListHead
,
305 IN PLIST_ENTRY ListEntry
,
308 * FUNCTION: Inserts an entry at the tail of a doubly linked list
310 * ListHead = Points to the head of the list
311 * ListEntry = Points to the entry to be inserted
312 * Lock = Caller supplied spinlock used to synchronize access
313 * RETURNS: The previous head of the list
319 KeAcquireSpinLock(Lock
,&oldlvl
);
320 if (IsListEmpty(ListHead
))
326 Old
= ListHead
->Blink
;
328 InsertTailList(ListHead
,ListEntry
);
329 KeReleaseSpinLock(Lock
,oldlvl
);
338 PSINGLE_LIST_ENTRY FASTCALL
339 ExfInterlockedPopEntryList(IN PSINGLE_LIST_ENTRY ListHead
,
342 * FUNCTION: Removes (pops) an entry from a singly list
344 * ListHead = Points to the head of the list
345 * Lock = Lock for synchronizing access to the list
346 * RETURNS: The removed entry
349 PSINGLE_LIST_ENTRY ret
;
352 KeAcquireSpinLock(Lock
,&oldlvl
);
353 ret
= PopEntryList(ListHead
);
354 KeReleaseSpinLock(Lock
,oldlvl
);
362 PSINGLE_LIST_ENTRY FASTCALL
363 ExfInterlockedPushEntryList(IN PSINGLE_LIST_ENTRY ListHead
,
364 IN PSINGLE_LIST_ENTRY ListEntry
,
367 * FUNCTION: Inserts (pushes) an entry into a singly linked list
369 * ListHead = Points to the head of the list
370 * ListEntry = Points to the entry to be inserted
371 * Lock = Caller supplied spinlock used to synchronize access
372 * RETURNS: The previous head of the list
376 PSINGLE_LIST_ENTRY ret
;
378 KeAcquireSpinLock(Lock
,&oldlvl
);
380 PushEntryList(ListHead
,ListEntry
);
381 KeReleaseSpinLock(Lock
,oldlvl
);
390 ExfInterlockedRemoveHeadList(IN PLIST_ENTRY Head
,
393 * FUNCTION: Removes the head of a double linked list
395 * Head = Points to the head of the list
396 * Lock = Lock for synchronizing access to the list
397 * RETURNS: The removed entry
403 KeAcquireSpinLock(Lock
,&oldlvl
);
404 if (IsListEmpty(Head
))
410 ret
= RemoveHeadList(Head
);
412 KeReleaseSpinLock(Lock
,oldlvl
);