2 Linked List Library Functions.
4 Copyright (c) 2006, Intel Corporation<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 Module Name: LinkedList.c
20 IN CONST LIST_ENTRY
*List
,
21 IN CONST LIST_ENTRY
*Node
25 CONST LIST_ENTRY
*Ptr
;
29 // Test the validity of List and Node
31 ASSERT (List
!= NULL
);
32 ASSERT (List
->ForwardLink
!= NULL
);
33 ASSERT (List
->BackLink
!= NULL
);
34 ASSERT (Node
!= NULL
);
36 Count
= PcdGet32 (PcdMaximumLinkedListLength
);
40 Ptr
= Ptr
->ForwardLink
;
42 } while ((Ptr
!= List
) && (Ptr
!= Node
) && (Count
> 0));
43 Found
= (BOOLEAN
)(Ptr
== Node
);
45 if (PcdGet32 (PcdMaximumLinkedListLength
) > 0) {
46 while ((Count
> 0) && (Ptr
!= List
)) {
47 Ptr
= Ptr
->ForwardLink
;
57 Initializes the head node of a doubly linked list, and returns the pointer to
58 the head node of the doubly linked list.
60 Initializes the forward and backward links of a new linked list. After
61 initializing a linked list with this function, the other linked list
62 functions may be used to add and remove nodes from the linked list. It is up
63 to the caller of this function to allocate the memory for ListHead.
65 If ListHead is NULL, then ASSERT().
67 @param ListHead A pointer to the head node of a new doubly linked list.
75 IN OUT LIST_ENTRY
*List
79 ASSERT (List
!= NULL
);
81 List
->ForwardLink
= List
;
82 List
->BackLink
= List
;
87 Adds a node to the beginning of a doubly linked list, and returns the pointer
88 to the head node of the doubly linked list.
90 Adds the node Entry at the beginning of the doubly linked list denoted by
91 ListHead, and returns ListHead.
93 If ListHead is NULL, then ASSERT().
94 If Entry is NULL, then ASSERT().
95 If ListHead was not initialized with InitializeListHead(), then ASSERT().
96 If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number
97 of nodes in ListHead, including the ListHead node, is greater than or
98 equal to PcdMaximumLinkedListLength, then ASSERT().
100 @param ListHead A pointer to the head node of a doubly linked list.
101 @param Entry A pointer to a node that is to be inserted at the beginning
102 of a doubly linked list.
110 IN OUT LIST_ENTRY
*List
,
111 IN OUT LIST_ENTRY
*Entry
115 // ASSERT List not too long and Entry is not one of the nodes of List
117 ASSERT (!IsNodeInList (List
, Entry
));
119 Entry
->ForwardLink
= List
->ForwardLink
;
120 Entry
->BackLink
= List
;
121 Entry
->ForwardLink
->BackLink
= Entry
;
122 List
->ForwardLink
= Entry
;
127 Adds a node to the end of a doubly linked list, and returns the pointer to
128 the head node of the doubly linked list.
130 Adds the node Entry to the end of the doubly linked list denoted by ListHead,
131 and returns ListHead.
133 If ListHead is NULL, then ASSERT().
134 If Entry is NULL, then ASSERT().
135 If ListHead was not initialized with InitializeListHead(), then ASSERT().
136 If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number
137 of nodes in ListHead, including the ListHead node, is greater than or
138 equal to PcdMaximumLinkedListLength, then ASSERT().
140 @param ListHead A pointer to the head node of a doubly linked list.
141 @param Entry A pointer to a node that is to be added at the end of the
150 IN OUT LIST_ENTRY
*List
,
151 IN OUT LIST_ENTRY
*Entry
155 // ASSERT List not too long and Entry is not one of the nodes of List
157 ASSERT (!IsNodeInList (List
, Entry
));
159 Entry
->ForwardLink
= List
;
160 Entry
->BackLink
= List
->BackLink
;
161 Entry
->BackLink
->ForwardLink
= Entry
;
162 List
->BackLink
= Entry
;
167 Retrieves the first node of a doubly linked list.
169 Returns the first node of a doubly linked list. List must have been
170 initialized with InitializeListHead(). If List is empty, then NULL is
173 If List is NULL, then ASSERT().
174 If List was not initialized with InitializeListHead(), then ASSERT().
175 If PcdMaximumLinkedListLenth is not zero, and the number of nodes
176 in List, including the List node, is greater than or equal to
177 PcdMaximumLinkedListLength, then ASSERT().
179 @param List A pointer to the head node of a doubly linked list.
181 @return The first node of a doubly linked list.
182 @retval NULL The list is empty.
188 IN CONST LIST_ENTRY
*List
192 // ASSERT List not too long
194 ASSERT (IsNodeInList (List
, List
));
196 return List
->ForwardLink
;
200 Retrieves the next node of a doubly linked list.
202 Returns the node of a doubly linked list that follows Node. List must have
203 been initialized with InitializeListHead(). If List is empty, then List is
206 If List is NULL, then ASSERT().
207 If Node is NULL, then ASSERT().
208 If List was not initialized with InitializeListHead(), then ASSERT().
209 If PcdMaximumLinkedListLenth is not zero, and List contains more than
210 PcdMaximumLinkedListLenth nodes, then ASSERT().
211 If Node is not a node in List, then ASSERT().
213 @param List A pointer to the head node of a doubly linked list.
214 @param Node A pointer to a node in the doubly linked list.
216 @return Pointer to the next node if one exists. Otherwise a null value which
217 is actually List is returned.
223 IN CONST LIST_ENTRY
*List
,
224 IN CONST LIST_ENTRY
*Node
228 // ASSERT List not too long and Node is one of the nodes of List
230 ASSERT (IsNodeInList (List
, Node
));
232 return Node
->ForwardLink
;
236 Checks to see if a doubly linked list is empty or not.
238 Checks to see if the doubly linked list is empty. If the linked list contains
239 zero nodes, this function returns TRUE. Otherwise, it returns FALSE.
241 If ListHead is NULL, then ASSERT().
242 If ListHead was not initialized with InitializeListHead(), then ASSERT().
243 If PcdMaximumLinkedListLenth is not zero, and the number of nodes
244 in List, including the List node, is greater than or equal to
245 PcdMaximumLinkedListLength, then ASSERT().
247 @param ListHead A pointer to the head node of a doubly linked list.
249 @retval TRUE The linked list is empty.
250 @retval FALSE The linked list is not empty.
256 IN CONST LIST_ENTRY
*List
260 // ASSERT List not too long
262 ASSERT (IsNodeInList (List
, List
));
264 return (BOOLEAN
)(List
->ForwardLink
== List
);
268 Determines if a node in a doubly linked list is null.
270 Returns FALSE if Node is one of the nodes in the doubly linked list specified
271 by List. Otherwise, TRUE is returned. List must have been initialized with
272 InitializeListHead().
274 If List is NULL, then ASSERT().
275 If Node is NULL, then ASSERT().
276 If List was not initialized with InitializeListHead(), then ASSERT().
277 If PcdMaximumLinkedListLenth is not zero, and the number of nodes
278 in List, including the List node, is greater than or equal to
279 PcdMaximumLinkedListLength, then ASSERT().
280 If Node is not a node in List and Node is not equal to List, then ASSERT().
282 @param List A pointer to the head node of a doubly linked list.
283 @param Node A pointer to a node in the doubly linked list.
285 @retval TRUE Node is one of the nodes in the doubly linked list.
286 @retval FALSE Node is not one of the nodes in the doubly linked list.
292 IN CONST LIST_ENTRY
*List
,
293 IN CONST LIST_ENTRY
*Node
297 // ASSERT List not too long and Node is one of the nodes of List
299 ASSERT (IsNodeInList (List
, Node
));
301 return (BOOLEAN
)(Node
== List
);
305 Determines if a node the last node in a doubly linked list.
307 Returns TRUE if Node is the last node in the doubly linked list specified by
308 List. Otherwise, FALSE is returned. List must have been initialized with
309 InitializeListHead().
311 If List is NULL, then ASSERT().
312 If Node is NULL, then ASSERT().
313 If List was not initialized with InitializeListHead(), then ASSERT().
314 If PcdMaximumLinkedListLenth is not zero, and the number of nodes
315 in List, including the List node, is greater than or equal to
316 PcdMaximumLinkedListLength, then ASSERT().
317 If Node is not a node in List, then ASSERT().
319 @param List A pointer to the head node of a doubly linked list.
320 @param Node A pointer to a node in the doubly linked list.
322 @retval TRUE Node is the last node in the linked list.
323 @retval FALSE Node is not the last node in the linked list.
329 IN CONST LIST_ENTRY
*List
,
330 IN CONST LIST_ENTRY
*Node
334 // ASSERT List not too long and Node is one of the nodes of List
336 ASSERT (IsNodeInList (List
, Node
));
338 return (BOOLEAN
)(!IsNull (List
, Node
) && List
->BackLink
== Node
);
342 Swaps the location of two nodes in a doubly linked list, and returns the
343 first node after the swap.
345 If FirstEntry is identical to SecondEntry, then SecondEntry is returned.
346 Otherwise, the location of the FirstEntry node is swapped with the location
347 of the SecondEntry node in a doubly linked list. SecondEntry must be in the
348 same double linked list as FirstEntry and that double linked list must have
349 been initialized with InitializeListHead(). SecondEntry is returned after the
352 If FirstEntry is NULL, then ASSERT().
353 If SecondEntry is NULL, then ASSERT().
354 If SecondEntry and FirstEntry are not in the same linked list, then ASSERT().
355 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
356 linked list containing the FirstEntry and SecondEntry nodes, including
357 the FirstEntry and SecondEntry nodes, is greater than or equal to
358 PcdMaximumLinkedListLength, then ASSERT().
360 @param FirstEntry A pointer to a node in a linked list.
361 @param SecondEntry A pointer to another node in the same linked list.
367 IN OUT LIST_ENTRY
*FirstEntry
,
368 IN OUT LIST_ENTRY
*SecondEntry
373 if (FirstEntry
== SecondEntry
) {
378 // ASSERT Entry1 and Entry2 are in the same linked list
380 ASSERT (IsNodeInList (FirstEntry
, SecondEntry
));
383 // Ptr is the node pointed to by FirstEntry->ForwardLink
385 Ptr
= RemoveEntryList (FirstEntry
);
388 // If FirstEntry immediately follows SecondEntry, FirstEntry willl be placed
389 // immediately in front of SecondEntry
391 if (Ptr
->BackLink
== SecondEntry
) {
392 return InsertTailList (SecondEntry
, FirstEntry
);
396 // Ptr == SecondEntry means SecondEntry immediately follows FirstEntry,
397 // then there are no further steps necessary
399 if (Ptr
== InsertHeadList (SecondEntry
, FirstEntry
)) {
404 // Move SecondEntry to the front of Ptr
406 RemoveEntryList (SecondEntry
);
407 InsertTailList (Ptr
, SecondEntry
);
412 Removes a node from a doubly linked list, and returns the node that follows
415 Removes the node Entry from a doubly linked list. It is up to the caller of
416 this function to release the memory used by this node if that is required. On
417 exit, the node following Entry in the doubly linked list is returned. If
418 Entry is the only node in the linked list, then the head node of the linked
421 If Entry is NULL, then ASSERT().
422 If Entry is the head node of an empty list, then ASSERT().
423 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the
424 linked list containing Entry, including the Entry node, is greater than
425 or equal to PcdMaximumLinkedListLength, then ASSERT().
427 @param Entry A pointer to a node in a linked list
435 IN CONST LIST_ENTRY
*Entry
438 ASSERT (!IsListEmpty (Entry
));
440 Entry
->ForwardLink
->BackLink
= Entry
->BackLink
;
441 Entry
->BackLink
->ForwardLink
= Entry
->ForwardLink
;
442 return Entry
->ForwardLink
;