32da5004ba01f96bc76d5eb9057cd14d85d94ade
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/rtl/list.c
5 * PURPOSE: Manages linked lists
6 * PROGRAMMER: David Welch (welch@mcmail.com)
9 /* INCLUDES *****************************************************************/
12 #include <ddk/ntddk.h>
15 #include <internal/debug.h>
17 /* FUNCTIONS *************************************************************/
19 static BOOLEAN
CheckEntry(PLIST_ENTRY ListEntry
)
21 assert(ListEntry
!=NULL
);
22 assert(ListEntry
->Blink
!=NULL
);
23 assert(ListEntry
->Blink
->Flink
!=NULL
);
24 assert(ListEntry
->Flink
!=NULL
);
25 assert(ListEntry
->Flink
->Blink
!=NULL
);
29 BOOLEAN
IsListEmpty(PLIST_ENTRY ListHead
)
31 * FUNCTION: Determines if a list is empty
33 * ListHead = Head of the list
34 * RETURNS: True if there are no entries in the list
37 return(ListHead
->Flink
==ListHead
);
40 VOID
RemoveEntryList(PLIST_ENTRY ListEntry
)
45 DPRINT("RemoveEntryList(ListEntry %x)\n", ListEntry
);
47 assert(CheckEntry(ListEntry
));
49 OldFlink
=ListEntry
->Flink
;
50 OldBlink
=ListEntry
->Blink
;
52 OldFlink
->Blink
=OldBlink
;
53 OldBlink
->Flink
=OldFlink
;
55 assert(CheckEntry(ListEntry
));
57 DPRINT("RemoveEntryList()\n");
60 PLIST_ENTRY
RemoveTailList(PLIST_ENTRY ListHead
)
62 * FUNCTION: Remove the tail entry from a double linked list
64 * ListHead = Head of the list to remove from
65 * RETURNS: The removed entry
68 PLIST_ENTRY Old
= ListHead
->Blink
;
69 RemoveEntryList(ListHead
->Blink
);
73 PLIST_ENTRY
RemoveHeadList(PLIST_ENTRY ListHead
)
77 DPRINT("RemoveHeadList(ListHead %x)\n",ListHead
);
79 assert(CheckEntry(ListHead
));
81 Old
= ListHead
->Flink
;
82 RemoveEntryList(ListHead
->Flink
);
84 assert(CheckEntry(ListHead
));
86 DPRINT("RemoveHeadList()\n");
91 VOID
InitializeListHead(PLIST_ENTRY ListHead
)
93 * FUNCTION: Initializes a double linked list
95 * ListHead = Caller supplied storage for the head of the list
98 ListHead
->Flink
= ListHead
->Blink
= ListHead
;
101 VOID
InsertTailList(PLIST_ENTRY ListHead
, PLIST_ENTRY ListEntry
)
103 * FUNCTION: Inserts an entry in a double linked list
105 * ListHead = Head of the list
106 * Entry = Entry to insert
111 Blink
= ListHead
->Blink
;
112 ListEntry
->Flink
=ListHead
;
113 ListEntry
->Blink
=Blink
;
114 Blink
->Flink
=ListEntry
;
115 ListHead
->Blink
=ListEntry
;
118 VOID
InsertHeadList(PLIST_ENTRY ListHead
, PLIST_ENTRY ListEntry
)
120 PLIST_ENTRY OldFlink
;
122 OldFlink
= ListHead
->Flink
;
123 ListEntry
->Flink
= OldFlink
;
124 ListEntry
->Blink
= ListHead
;
125 OldFlink
->Blink
= ListEntry
;
126 ListHead
->Flink
= ListEntry
;
129 PLIST_ENTRY
ExInterlockedInsertTailList(PLIST_ENTRY ListHead
,
130 PLIST_ENTRY ListEntry
,
136 KeAcquireSpinLock(Lock
,&oldlvl
);
137 if (IsListEmpty(ListHead
))
143 Old
= ListHead
->Blink
;
145 InsertTailList(ListHead
,ListEntry
);
146 KeReleaseSpinLock(Lock
,oldlvl
);
151 PLIST_ENTRY
ExInterlockedInsertHeadList(PLIST_ENTRY ListHead
,
152 PLIST_ENTRY ListEntry
,
155 * FUNCTION: Inserts an entry at the head of a doubly linked list
157 * ListHead = Points to the head of the list
158 * ListEntry = Points to the entry to be inserted
159 * Lock = Caller supplied spinlock used to synchronise access
160 * RETURNS: The previous head of the list
166 KeAcquireSpinLock(Lock
,&oldlvl
);
167 if (IsListEmpty(ListHead
))
173 Old
= ListHead
->Flink
;
175 InsertHeadList(ListHead
,ListEntry
);
176 KeReleaseSpinLock(Lock
,oldlvl
);
182 PLIST_ENTRY
ExInterlockedRemoveHeadList(PLIST_ENTRY Head
,
185 * FUNCTION: Removes the head of a double linked list
188 * Lock = Lock for synchronizing access to the list
189 * RETURNS: The removed entry
195 KeAcquireSpinLock(Lock
,&oldlvl
);
196 if (IsListEmpty(Head
))
202 ret
= RemoveHeadList(Head
);
204 KeReleaseSpinLock(Lock
,oldlvl
);
208 PLIST_ENTRY
ExInterlockedRemoveTailList(PLIST_ENTRY Head
,
211 * FUNCTION: Removes the tail of a double linked list
214 * Lock = Lock for synchronizing access to the list
215 * RETURNS: The removed entry
221 KeAcquireSpinLock(Lock
,&oldlvl
);
222 if (IsListEmpty(Head
))
228 ret
= RemoveTailList(Head
);
230 KeReleaseSpinLock(Lock
,oldlvl
);