1 /* $Id: list.c,v 1.5 2002/07/27 13:02:13 ekohl 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 *************************************************************/
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
;
298 InsertTailList(ListHead
,ListEntry
);
299 KeReleaseSpinLock(Lock
,oldlvl
);
305 PSINGLE_LIST_ENTRY FASTCALL
306 ExfInterlockedPopEntryList(IN PSINGLE_LIST_ENTRY ListHead
,
309 * FUNCTION: Removes (pops) an entry from a singly list
311 * ListHead = Points to the head of the list
312 * Lock = Lock for synchronizing access to the list
313 * RETURNS: The removed entry
316 PSINGLE_LIST_ENTRY ret
;
319 KeAcquireSpinLock(Lock
,&oldlvl
);
320 ret
= PopEntryList(ListHead
);
321 KeReleaseSpinLock(Lock
,oldlvl
);
326 PSINGLE_LIST_ENTRY FASTCALL
327 ExfInterlockedPushEntryList(IN PSINGLE_LIST_ENTRY ListHead
,
328 IN PSINGLE_LIST_ENTRY ListEntry
,
331 * FUNCTION: Inserts (pushes) an entry into a singly linked list
333 * ListHead = Points to the head of the list
334 * ListEntry = Points to the entry to be inserted
335 * Lock = Caller supplied spinlock used to synchronize access
336 * RETURNS: The previous head of the list
340 PSINGLE_LIST_ENTRY ret
;
342 KeAcquireSpinLock(Lock
,&oldlvl
);
344 PushEntryList(ListHead
,ListEntry
);
345 KeReleaseSpinLock(Lock
,oldlvl
);
351 ExfInterlockedRemoveHeadList(IN PLIST_ENTRY Head
,
354 * FUNCTION: Removes the head of a double linked list
356 * Head = Points to the head of the list
357 * Lock = Lock for synchronizing access to the list
358 * RETURNS: The removed entry
364 KeAcquireSpinLock(Lock
,&oldlvl
);
365 if (IsListEmpty(Head
))
371 ret
= RemoveHeadList(Head
);
373 KeReleaseSpinLock(Lock
,oldlvl
);