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