]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/LinkedList.c
MdePkg: Clean up source files
[mirror_edk2.git] / MdePkg / Library / BaseLib / LinkedList.c
CommitLineData
e1f414b6 1/** @file\r
2 Linked List Library Functions.\r
3\r
9095d37b 4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
bb817c56 5 This program and the accompanying materials\r
e1f414b6 6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
127010dd 8 http://opensource.org/licenses/bsd-license.php.\r
e1f414b6 9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
e1f414b6 13**/\r
14\r
e1f414b6 15#include "BaseLibInternals.h"\r
16\r
17/**\r
9062381a
MH
18 If PcdVerifyNodeInList is TRUE, ASSERTs when SecondEntry is or is not part of\r
19 the same doubly-linked list as FirstEntry depending on the value of InList.\r
20 Independent of PcdVerifyNodeInList, ASSERTs when FirstEntry is not part of a\r
21 valid list.\r
e1f414b6 22\r
9062381a
MH
23 If FirstEntry is NULL, then ASSERT().\r
24 If FirstEntry->ForwardLink is NULL, then ASSERT().\r
25 If FirstEntry->BackLink is NULL, then ASSERT().\r
26 If PcdMaximumLinkedListLength is not zero, and List contains more than\r
27 PcdMaximumLinkedListLength nodes, then ASSERT().\r
28 If PcdVerifyNodeInList is TRUE and SecondEntry is NULL, then ASSERT().\r
29\r
30 @param FirstEntry A pointer to a node in a linked list.\r
31 @param SecondEntry A pointer to the node to locate.\r
32 @param InList Defines whether to check if SecondEntry is or is not part\r
33 of the same doubly-linked list as FirstEntry.\r
34\r
35**/\r
36#if !defined (MDEPKG_NDEBUG)\r
37 #define ASSERT_VERIFY_NODE_IN_VALID_LIST(FirstEntry, SecondEntry, InList) \\r
38 do { \\r
39 if (FeaturePcdGet (PcdVerifyNodeInList)) { \\r
40 ASSERT (InList == IsNodeInList ((FirstEntry), (SecondEntry))); \\r
41 } else { \\r
42 ASSERT (InternalBaseLibIsListValid (FirstEntry)); \\r
43 } \\r
44 } while (FALSE)\r
45#else\r
46 #define ASSERT_VERIFY_NODE_IN_VALID_LIST(FirstEntry, SecondEntry, InList)\r
47#endif\r
48\r
49/**\r
50 Worker function that verifies the validity of this list.\r
e1f414b6 51\r
52 If List is NULL, then ASSERT().\r
53 If List->ForwardLink is NULL, then ASSERT().\r
9062381a 54 If List->BackLink is NULL, then ASSERT().\r
a71865b1
LG
55 If PcdMaximumLinkedListLength is not zero, and List contains more than\r
56 PcdMaximumLinkedListLength nodes, then ASSERT().\r
e1f414b6 57\r
1081f624 58 @param List A pointer to a node in a linked list.\r
e1f414b6 59\r
1081f624 60 @retval TRUE if PcdVerifyNodeInList is FALSE\r
61 @retval TRUE if DoMembershipCheck is FALSE\r
9095d37b 62 @retval TRUE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE\r
1081f624 63 and Node is a member of List.\r
9095d37b 64 @retval FALSE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE\r
1081f624 65 and Node is in not a member of List.\r
e1f414b6 66\r
67**/\r
68BOOLEAN\r
38bbd3d9 69EFIAPI\r
9062381a
MH
70InternalBaseLibIsListValid (\r
71 IN CONST LIST_ENTRY *List\r
e1f414b6 72 )\r
73{\r
1081f624 74 UINTN Count;\r
75 CONST LIST_ENTRY *Ptr;\r
e1f414b6 76\r
77 //\r
78 // Test the validity of List and Node\r
79 //\r
80 ASSERT (List != NULL);\r
81 ASSERT (List->ForwardLink != NULL);\r
82 ASSERT (List->BackLink != NULL);\r
e1f414b6 83\r
84 if (PcdGet32 (PcdMaximumLinkedListLength) > 0) {\r
9062381a
MH
85 Count = 0;\r
86 Ptr = List;\r
87\r
1081f624 88 //\r
89 // Count the total number of nodes in List.\r
90 // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength\r
91 //\r
92 do {\r
e1f414b6 93 Ptr = Ptr->ForwardLink;\r
1081f624 94 Count++;\r
95 } while ((Ptr != List) && (Count < PcdGet32 (PcdMaximumLinkedListLength)));\r
96\r
97 //\r
9062381a 98 // return whether linked list is too long\r
1081f624 99 //\r
9062381a 100 return (BOOLEAN)(Count < PcdGet32 (PcdMaximumLinkedListLength));\r
e1f414b6 101 }\r
102\r
1081f624 103 return TRUE;\r
e1f414b6 104}\r
105\r
d0aef615
MH
106/**\r
107 Checks whether FirstEntry and SecondEntry are part of the same doubly-linked\r
108 list.\r
109\r
110 If FirstEntry is NULL, then ASSERT().\r
111 If FirstEntry->ForwardLink is NULL, then ASSERT().\r
112 If FirstEntry->BackLink is NULL, then ASSERT().\r
113 If SecondEntry is NULL, then ASSERT();\r
114 If PcdMaximumLinkedListLength is not zero, and List contains more than\r
115 PcdMaximumLinkedListLength nodes, then ASSERT().\r
116\r
117 @param FirstEntry A pointer to a node in a linked list.\r
118 @param SecondEntry A pointer to the node to locate.\r
119\r
120 @retval TRUE SecondEntry is in the same doubly-linked list as FirstEntry.\r
121 @retval FALSE SecondEntry isn't in the same doubly-linked list as FirstEntry,\r
122 or FirstEntry is invalid.\r
123\r
124**/\r
125BOOLEAN\r
126EFIAPI\r
127IsNodeInList (\r
128 IN CONST LIST_ENTRY *FirstEntry,\r
129 IN CONST LIST_ENTRY *SecondEntry\r
130 )\r
131{\r
132 UINTN Count;\r
133 CONST LIST_ENTRY *Ptr;\r
134\r
135 //\r
136 // ASSERT List not too long\r
137 //\r
138 ASSERT (InternalBaseLibIsListValid (FirstEntry));\r
139\r
140 ASSERT (SecondEntry != NULL);\r
141\r
142 Count = 0;\r
143 Ptr = FirstEntry;\r
144\r
145 //\r
9095d37b 146 // Check to see if SecondEntry is a member of FirstEntry.\r
d0aef615
MH
147 // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength\r
148 //\r
149 do {\r
150 Ptr = Ptr->ForwardLink;\r
151 if (PcdGet32 (PcdMaximumLinkedListLength) > 0) {\r
152 Count++;\r
153\r
154 //\r
155 // Return if the linked list is too long\r
156 //\r
157 if (Count == PcdGet32 (PcdMaximumLinkedListLength)) {\r
158 return (BOOLEAN)(Ptr == SecondEntry);\r
159 }\r
160 }\r
161\r
162 if (Ptr == SecondEntry) {\r
163 return TRUE;\r
164 }\r
165 } while (Ptr != FirstEntry);\r
166\r
167 return FALSE;\r
168}\r
169\r
e1f414b6 170/**\r
127010dd 171 Initializes the head node of a doubly-linked list, and returns the pointer to\r
172 the head node of the doubly-linked list.\r
e1f414b6 173\r
174 Initializes the forward and backward links of a new linked list. After\r
175 initializing a linked list with this function, the other linked list\r
176 functions may be used to add and remove nodes from the linked list. It is up\r
177 to the caller of this function to allocate the memory for ListHead.\r
178\r
179 If ListHead is NULL, then ASSERT().\r
180\r
127010dd 181 @param ListHead A pointer to the head node of a new doubly-linked list.\r
e1f414b6 182\r
183 @return ListHead\r
184\r
185**/\r
186LIST_ENTRY *\r
187EFIAPI\r
188InitializeListHead (\r
2fc60b70 189 IN OUT LIST_ENTRY *ListHead\r
e1f414b6 190 )\r
191\r
192{\r
2fc60b70 193 ASSERT (ListHead != NULL);\r
e1f414b6 194\r
2fc60b70 195 ListHead->ForwardLink = ListHead;\r
196 ListHead->BackLink = ListHead;\r
197 return ListHead;\r
e1f414b6 198}\r
199\r
200/**\r
127010dd 201 Adds a node to the beginning of a doubly-linked list, and returns the pointer\r
202 to the head node of the doubly-linked list.\r
e1f414b6 203\r
127010dd 204 Adds the node Entry at the beginning of the doubly-linked list denoted by\r
e1f414b6 205 ListHead, and returns ListHead.\r
206\r
207 If ListHead is NULL, then ASSERT().\r
208 If Entry is NULL, then ASSERT().\r
9aa049d9 209 If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
210 InitializeListHead(), then ASSERT().\r
a71865b1 211 If PcdMaximumLinkedListLength is not zero, and prior to insertion the number\r
e1f414b6 212 of nodes in ListHead, including the ListHead node, is greater than or\r
213 equal to PcdMaximumLinkedListLength, then ASSERT().\r
214\r
127010dd 215 @param ListHead A pointer to the head node of a doubly-linked list.\r
e1f414b6 216 @param Entry A pointer to a node that is to be inserted at the beginning\r
127010dd 217 of a doubly-linked list.\r
e1f414b6 218\r
219 @return ListHead\r
220\r
221**/\r
222LIST_ENTRY *\r
223EFIAPI\r
224InsertHeadList (\r
2fc60b70 225 IN OUT LIST_ENTRY *ListHead,\r
226 IN OUT LIST_ENTRY *Entry\r
e1f414b6 227 )\r
228{\r
229 //\r
230 // ASSERT List not too long and Entry is not one of the nodes of List\r
231 //\r
9062381a 232 ASSERT_VERIFY_NODE_IN_VALID_LIST (ListHead, Entry, FALSE);\r
9095d37b 233\r
2fc60b70 234 Entry->ForwardLink = ListHead->ForwardLink;\r
235 Entry->BackLink = ListHead;\r
e1f414b6 236 Entry->ForwardLink->BackLink = Entry;\r
2fc60b70 237 ListHead->ForwardLink = Entry;\r
238 return ListHead;\r
e1f414b6 239}\r
240\r
241/**\r
127010dd 242 Adds a node to the end of a doubly-linked list, and returns the pointer to\r
243 the head node of the doubly-linked list.\r
e1f414b6 244\r
127010dd 245 Adds the node Entry to the end of the doubly-linked list denoted by ListHead,\r
e1f414b6 246 and returns ListHead.\r
247\r
248 If ListHead is NULL, then ASSERT().\r
249 If Entry is NULL, then ASSERT().\r
9095d37b 250 If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
9aa049d9 251 InitializeListHead(), then ASSERT().\r
a71865b1 252 If PcdMaximumLinkedListLength is not zero, and prior to insertion the number\r
e1f414b6 253 of nodes in ListHead, including the ListHead node, is greater than or\r
254 equal to PcdMaximumLinkedListLength, then ASSERT().\r
255\r
127010dd 256 @param ListHead A pointer to the head node of a doubly-linked list.\r
e1f414b6 257 @param Entry A pointer to a node that is to be added at the end of the\r
127010dd 258 doubly-linked list.\r
e1f414b6 259\r
260 @return ListHead\r
261\r
262**/\r
263LIST_ENTRY *\r
264EFIAPI\r
265InsertTailList (\r
2fc60b70 266 IN OUT LIST_ENTRY *ListHead,\r
267 IN OUT LIST_ENTRY *Entry\r
e1f414b6 268 )\r
269{\r
270 //\r
271 // ASSERT List not too long and Entry is not one of the nodes of List\r
272 //\r
9062381a 273 ASSERT_VERIFY_NODE_IN_VALID_LIST (ListHead, Entry, FALSE);\r
9095d37b 274\r
2fc60b70 275 Entry->ForwardLink = ListHead;\r
276 Entry->BackLink = ListHead->BackLink;\r
e1f414b6 277 Entry->BackLink->ForwardLink = Entry;\r
2fc60b70 278 ListHead->BackLink = Entry;\r
279 return ListHead;\r
e1f414b6 280}\r
281\r
282/**\r
127010dd 283 Retrieves the first node of a doubly-linked list.\r
e1f414b6 284\r
9095d37b 285 Returns the first node of a doubly-linked list. List must have been\r
9aa049d9 286 initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r
287 If List is empty, then List is returned.\r
e1f414b6 288\r
289 If List is NULL, then ASSERT().\r
9095d37b 290 If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
9aa049d9 291 InitializeListHead(), then ASSERT().\r
a71865b1 292 If PcdMaximumLinkedListLength is not zero, and the number of nodes\r
e1f414b6 293 in List, including the List node, is greater than or equal to\r
294 PcdMaximumLinkedListLength, then ASSERT().\r
295\r
127010dd 296 @param List A pointer to the head node of a doubly-linked list.\r
e1f414b6 297\r
127010dd 298 @return The first node of a doubly-linked list.\r
e01a125f 299 @retval List The list is empty.\r
e1f414b6 300\r
301**/\r
302LIST_ENTRY *\r
303EFIAPI\r
304GetFirstNode (\r
2fc60b70 305 IN CONST LIST_ENTRY *List\r
e1f414b6 306 )\r
307{\r
308 //\r
309 // ASSERT List not too long\r
310 //\r
9062381a 311 ASSERT (InternalBaseLibIsListValid (List));\r
e1f414b6 312\r
313 return List->ForwardLink;\r
314}\r
315\r
316/**\r
127010dd 317 Retrieves the next node of a doubly-linked list.\r
e1f414b6 318\r
9095d37b 319 Returns the node of a doubly-linked list that follows Node.\r
9aa049d9 320 List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()\r
321 or InitializeListHead(). If List is empty, then List is returned.\r
e1f414b6 322\r
323 If List is NULL, then ASSERT().\r
324 If Node is NULL, then ASSERT().\r
9095d37b 325 If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
9aa049d9 326 InitializeListHead(), then ASSERT().\r
a71865b1
LG
327 If PcdMaximumLinkedListLength is not zero, and List contains more than\r
328 PcdMaximumLinkedListLength nodes, then ASSERT().\r
1081f624 329 If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
e1f414b6 330\r
127010dd 331 @param List A pointer to the head node of a doubly-linked list.\r
332 @param Node A pointer to a node in the doubly-linked list.\r
e1f414b6 333\r
127010dd 334 @return A pointer to the next node if one exists. Otherwise List is returned.\r
e1f414b6 335\r
336**/\r
337LIST_ENTRY *\r
338EFIAPI\r
339GetNextNode (\r
2fc60b70 340 IN CONST LIST_ENTRY *List,\r
341 IN CONST LIST_ENTRY *Node\r
e1f414b6 342 )\r
343{\r
344 //\r
345 // ASSERT List not too long and Node is one of the nodes of List\r
346 //\r
9062381a 347 ASSERT_VERIFY_NODE_IN_VALID_LIST (List, Node, TRUE);\r
e1f414b6 348\r
349 return Node->ForwardLink;\r
350}\r
351\r
cbca8de5 352/**\r
127010dd 353 Retrieves the previous node of a doubly-linked list.\r
9095d37b
LG
354\r
355 Returns the node of a doubly-linked list that precedes Node.\r
cbca8de5 356 List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()\r
357 or InitializeListHead(). If List is empty, then List is returned.\r
9095d37b 358\r
cbca8de5 359 If List is NULL, then ASSERT().\r
360 If Node is NULL, then ASSERT().\r
9095d37b 361 If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
cbca8de5 362 InitializeListHead(), then ASSERT().\r
a71865b1
LG
363 If PcdMaximumLinkedListLength is not zero, and List contains more than\r
364 PcdMaximumLinkedListLength nodes, then ASSERT().\r
cbca8de5 365 If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
9095d37b 366\r
127010dd 367 @param List A pointer to the head node of a doubly-linked list.\r
368 @param Node A pointer to a node in the doubly-linked list.\r
9095d37b 369\r
127010dd 370 @return A pointer to the previous node if one exists. Otherwise List is returned.\r
9095d37b 371\r
cbca8de5 372**/\r
373LIST_ENTRY *\r
374EFIAPI\r
375GetPreviousNode (\r
376 IN CONST LIST_ENTRY *List,\r
377 IN CONST LIST_ENTRY *Node\r
378 )\r
379{\r
380 //\r
381 // ASSERT List not too long and Node is one of the nodes of List\r
382 //\r
9062381a 383 ASSERT_VERIFY_NODE_IN_VALID_LIST (List, Node, TRUE);\r
9095d37b 384\r
cbca8de5 385 return Node->BackLink;\r
386}\r
387\r
e1f414b6 388/**\r
127010dd 389 Checks to see if a doubly-linked list is empty or not.\r
e1f414b6 390\r
127010dd 391 Checks to see if the doubly-linked list is empty. If the linked list contains\r
e1f414b6 392 zero nodes, this function returns TRUE. Otherwise, it returns FALSE.\r
393\r
394 If ListHead is NULL, then ASSERT().\r
9095d37b 395 If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
9aa049d9 396 InitializeListHead(), then ASSERT().\r
a71865b1 397 If PcdMaximumLinkedListLength is not zero, and the number of nodes\r
e1f414b6 398 in List, including the List node, is greater than or equal to\r
399 PcdMaximumLinkedListLength, then ASSERT().\r
400\r
127010dd 401 @param ListHead A pointer to the head node of a doubly-linked list.\r
e1f414b6 402\r
403 @retval TRUE The linked list is empty.\r
404 @retval FALSE The linked list is not empty.\r
405\r
406**/\r
407BOOLEAN\r
408EFIAPI\r
409IsListEmpty (\r
2fc60b70 410 IN CONST LIST_ENTRY *ListHead\r
e1f414b6 411 )\r
412{\r
413 //\r
414 // ASSERT List not too long\r
415 //\r
9062381a 416 ASSERT (InternalBaseLibIsListValid (ListHead));\r
9095d37b 417\r
2fc60b70 418 return (BOOLEAN)(ListHead->ForwardLink == ListHead);\r
e1f414b6 419}\r
420\r
421/**\r
127010dd 422 Determines if a node in a doubly-linked list is the head node of a the same\r
423 doubly-linked list. This function is typically used to terminate a loop that\r
424 traverses all the nodes in a doubly-linked list starting with the head node.\r
e1f414b6 425\r
aa0583c7 426 Returns TRUE if Node is equal to List. Returns FALSE if Node is one of the\r
127010dd 427 nodes in the doubly-linked list specified by List. List must have been\r
9aa049d9 428 initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r
e1f414b6 429\r
430 If List is NULL, then ASSERT().\r
431 If Node is NULL, then ASSERT().\r
9095d37b 432 If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(),\r
9aa049d9 433 then ASSERT().\r
a71865b1 434 If PcdMaximumLinkedListLength is not zero, and the number of nodes\r
e1f414b6 435 in List, including the List node, is greater than or equal to\r
436 PcdMaximumLinkedListLength, then ASSERT().\r
9095d37b 437 If PcdVerifyNodeInList is TRUE and Node is not a node in List and Node is not\r
1081f624 438 equal to List, then ASSERT().\r
e1f414b6 439\r
127010dd 440 @param List A pointer to the head node of a doubly-linked list.\r
441 @param Node A pointer to a node in the doubly-linked list.\r
e1f414b6 442\r
1955808d
LG
443 @retval TRUE Node is the head of the doubly-linked list pointed by List.\r
444 @retval FALSE Node is not the head of the doubly-linked list pointed by List.\r
e1f414b6 445\r
446**/\r
447BOOLEAN\r
448EFIAPI\r
449IsNull (\r
2fc60b70 450 IN CONST LIST_ENTRY *List,\r
451 IN CONST LIST_ENTRY *Node\r
e1f414b6 452 )\r
453{\r
454 //\r
455 // ASSERT List not too long and Node is one of the nodes of List\r
456 //\r
9062381a 457 ASSERT_VERIFY_NODE_IN_VALID_LIST (List, Node, TRUE);\r
9095d37b 458\r
e1f414b6 459 return (BOOLEAN)(Node == List);\r
460}\r
461\r
462/**\r
127010dd 463 Determines if a node the last node in a doubly-linked list.\r
e1f414b6 464\r
127010dd 465 Returns TRUE if Node is the last node in the doubly-linked list specified by\r
e1f414b6 466 List. Otherwise, FALSE is returned. List must have been initialized with\r
9aa049d9 467 INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r
e1f414b6 468\r
469 If List is NULL, then ASSERT().\r
470 If Node is NULL, then ASSERT().\r
9aa049d9 471 If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r
472 InitializeListHead(), then ASSERT().\r
a71865b1 473 If PcdMaximumLinkedListLength is not zero, and the number of nodes\r
e1f414b6 474 in List, including the List node, is greater than or equal to\r
475 PcdMaximumLinkedListLength, then ASSERT().\r
1081f624 476 If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r
e1f414b6 477\r
127010dd 478 @param List A pointer to the head node of a doubly-linked list.\r
479 @param Node A pointer to a node in the doubly-linked list.\r
e1f414b6 480\r
481 @retval TRUE Node is the last node in the linked list.\r
482 @retval FALSE Node is not the last node in the linked list.\r
483\r
484**/\r
485BOOLEAN\r
486EFIAPI\r
487IsNodeAtEnd (\r
2fc60b70 488 IN CONST LIST_ENTRY *List,\r
489 IN CONST LIST_ENTRY *Node\r
e1f414b6 490 )\r
491{\r
492 //\r
493 // ASSERT List not too long and Node is one of the nodes of List\r
494 //\r
9062381a 495 ASSERT_VERIFY_NODE_IN_VALID_LIST (List, Node, TRUE);\r
9095d37b 496\r
e1f414b6 497 return (BOOLEAN)(!IsNull (List, Node) && List->BackLink == Node);\r
498}\r
499\r
500/**\r
127010dd 501 Swaps the location of two nodes in a doubly-linked list, and returns the\r
e1f414b6 502 first node after the swap.\r
503\r
504 If FirstEntry is identical to SecondEntry, then SecondEntry is returned.\r
505 Otherwise, the location of the FirstEntry node is swapped with the location\r
127010dd 506 of the SecondEntry node in a doubly-linked list. SecondEntry must be in the\r
e1f414b6 507 same double linked list as FirstEntry and that double linked list must have\r
9095d37b 508 been initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r
9aa049d9 509 SecondEntry is returned after the nodes are swapped.\r
e1f414b6 510\r
511 If FirstEntry is NULL, then ASSERT().\r
512 If SecondEntry is NULL, then ASSERT().\r
9095d37b 513 If PcdVerifyNodeInList is TRUE and SecondEntry and FirstEntry are not in the\r
1081f624 514 same linked list, then ASSERT().\r
e1f414b6 515 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r
516 linked list containing the FirstEntry and SecondEntry nodes, including\r
517 the FirstEntry and SecondEntry nodes, is greater than or equal to\r
518 PcdMaximumLinkedListLength, then ASSERT().\r
519\r
520 @param FirstEntry A pointer to a node in a linked list.\r
521 @param SecondEntry A pointer to another node in the same linked list.\r
9095d37b 522\r
9aa049d9 523 @return SecondEntry.\r
e1f414b6 524\r
525**/\r
526LIST_ENTRY *\r
527EFIAPI\r
528SwapListEntries (\r
2fc60b70 529 IN OUT LIST_ENTRY *FirstEntry,\r
530 IN OUT LIST_ENTRY *SecondEntry\r
e1f414b6 531 )\r
532{\r
533 LIST_ENTRY *Ptr;\r
534\r
535 if (FirstEntry == SecondEntry) {\r
536 return SecondEntry;\r
537 }\r
538\r
539 //\r
540 // ASSERT Entry1 and Entry2 are in the same linked list\r
541 //\r
9062381a 542 ASSERT_VERIFY_NODE_IN_VALID_LIST (FirstEntry, SecondEntry, TRUE);\r
9095d37b 543\r
e1f414b6 544 //\r
545 // Ptr is the node pointed to by FirstEntry->ForwardLink\r
546 //\r
547 Ptr = RemoveEntryList (FirstEntry);\r
548\r
549 //\r
24dcb5e5 550 // If FirstEntry immediately follows SecondEntry, FirstEntry will be placed\r
e1f414b6 551 // immediately in front of SecondEntry\r
552 //\r
553 if (Ptr->BackLink == SecondEntry) {\r
554 return InsertTailList (SecondEntry, FirstEntry);\r
555 }\r
556\r
557 //\r
558 // Ptr == SecondEntry means SecondEntry immediately follows FirstEntry,\r
559 // then there are no further steps necessary\r
560 //\r
561 if (Ptr == InsertHeadList (SecondEntry, FirstEntry)) {\r
562 return Ptr;\r
563 }\r
564\r
565 //\r
566 // Move SecondEntry to the front of Ptr\r
567 //\r
568 RemoveEntryList (SecondEntry);\r
569 InsertTailList (Ptr, SecondEntry);\r
570 return SecondEntry;\r
571}\r
572\r
573/**\r
127010dd 574 Removes a node from a doubly-linked list, and returns the node that follows\r
e1f414b6 575 the removed node.\r
576\r
127010dd 577 Removes the node Entry from a doubly-linked list. It is up to the caller of\r
e1f414b6 578 this function to release the memory used by this node if that is required. On\r
127010dd 579 exit, the node following Entry in the doubly-linked list is returned. If\r
e1f414b6 580 Entry is the only node in the linked list, then the head node of the linked\r
581 list is returned.\r
582\r
583 If Entry is NULL, then ASSERT().\r
584 If Entry is the head node of an empty list, then ASSERT().\r
585 If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r
586 linked list containing Entry, including the Entry node, is greater than\r
587 or equal to PcdMaximumLinkedListLength, then ASSERT().\r
588\r
9aa049d9 589 @param Entry A pointer to a node in a linked list.\r
e1f414b6 590\r
9aa049d9 591 @return Entry.\r
e1f414b6 592\r
593**/\r
594LIST_ENTRY *\r
595EFIAPI\r
596RemoveEntryList (\r
2fc60b70 597 IN CONST LIST_ENTRY *Entry\r
e1f414b6 598 )\r
599{\r
600 ASSERT (!IsListEmpty (Entry));\r
9095d37b 601\r
e1f414b6 602 Entry->ForwardLink->BackLink = Entry->BackLink;\r
603 Entry->BackLink->ForwardLink = Entry->ForwardLink;\r
604 return Entry->ForwardLink;\r
605}\r