]>
Commit | Line | Data |
---|---|---|
e1f414b6 | 1 | /** @file\r |
2 | Linked List Library Functions.\r | |
3 | \r | |
aa0583c7 | 4 | Copyright (c) 2006 - 2008, Intel Corporation<BR>\r |
e1f414b6 | 5 | All rights reserved. This program and the accompanying materials\r |
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 | |
8 | http://opensource.org/licenses/bsd-license.php\r | |
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 | |
2fc60b70 | 18 | Worker function that locates the Node in the List.\r |
e1f414b6 | 19 | \r |
20 | By searching the List, finds the location of the Node in List. At the same time,\r | |
21 | verifies the validity of this list.\r | |
22 | \r | |
23 | If List is NULL, then ASSERT().\r | |
24 | If List->ForwardLink is NULL, then ASSERT().\r | |
2fc60b70 | 25 | If List->backLink is NULL, then ASSERT().\r |
1081f624 | 26 | If Node is NULL, then ASSERT().\r |
27 | If PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE and Node \r | |
28 | is in not a member of List, then return FALSE\r | |
29 | If PcdMaximumLinkedListLenth is not zero, and List contains more than\r | |
30 | PcdMaximumLinkedListLenth nodes, then ASSERT().\r | |
e1f414b6 | 31 | \r |
1081f624 | 32 | @param List A pointer to a node in a linked list.\r |
33 | @param Node A pointer to a node in a linked list.\r | |
34 | @param VerifyNodeInList TRUE if a check should be made to see if Node is a \r | |
35 | member of List. FALSE if no membership test should \r | |
36 | be performed.\r | |
e1f414b6 | 37 | \r |
1081f624 | 38 | @retval TRUE if PcdVerifyNodeInList is FALSE\r |
39 | @retval TRUE if DoMembershipCheck is FALSE\r | |
40 | @retval TRUE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE \r | |
41 | and Node is a member of List.\r | |
42 | @retval FALSE if PcdVerifyNodeInList is TRUE and DoMembershipCheck is TRUE \r | |
43 | and Node is in not a member of List.\r | |
e1f414b6 | 44 | \r |
45 | **/\r | |
46 | BOOLEAN\r | |
38bbd3d9 | 47 | EFIAPI\r |
80151e53 | 48 | InternalBaseLibIsNodeInList (\r |
1081f624 | 49 | IN CONST LIST_ENTRY *List,\r |
50 | IN CONST LIST_ENTRY *Node,\r | |
51 | IN BOOLEAN VerifyNodeInList\r | |
e1f414b6 | 52 | )\r |
53 | {\r | |
1081f624 | 54 | UINTN Count;\r |
55 | CONST LIST_ENTRY *Ptr;\r | |
e1f414b6 | 56 | \r |
57 | //\r | |
58 | // Test the validity of List and Node\r | |
59 | //\r | |
60 | ASSERT (List != NULL);\r | |
61 | ASSERT (List->ForwardLink != NULL);\r | |
62 | ASSERT (List->BackLink != NULL);\r | |
63 | ASSERT (Node != NULL);\r | |
64 | \r | |
1081f624 | 65 | Count = 0;\r |
66 | Ptr = List;\r | |
e1f414b6 | 67 | \r |
1081f624 | 68 | if (FeaturePcdGet (PcdVerifyNodeInList) && VerifyNodeInList) {\r |
69 | //\r | |
70 | // Check to see if Node is a member of List. \r | |
71 | // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength\r | |
72 | //\r | |
73 | do {\r | |
74 | Ptr = Ptr->ForwardLink;\r | |
75 | if (PcdGet32 (PcdMaximumLinkedListLength) > 0) {\r | |
76 | Count++;\r | |
77 | //\r | |
78 | // ASSERT() if the linked list is too long\r | |
79 | //\r | |
80 | ASSERT (Count < PcdGet32 (PcdMaximumLinkedListLength));\r | |
81 | \r | |
82 | //\r | |
83 | // Return if the linked list is too long\r | |
84 | //\r | |
85 | if (Count >= PcdGet32 (PcdMaximumLinkedListLength)) {\r | |
86 | return (BOOLEAN)(Ptr == Node);\r | |
87 | }\r | |
88 | }\r | |
89 | } while ((Ptr != List) && (Ptr != Node)); \r | |
90 | \r | |
91 | if (Ptr != Node) {\r | |
92 | return FALSE;\r | |
93 | }\r | |
94 | }\r | |
e1f414b6 | 95 | \r |
96 | if (PcdGet32 (PcdMaximumLinkedListLength) > 0) {\r | |
1081f624 | 97 | //\r |
98 | // Count the total number of nodes in List.\r | |
99 | // Exit early if the number of nodes in List >= PcdMaximumLinkedListLength\r | |
100 | //\r | |
101 | do {\r | |
e1f414b6 | 102 | Ptr = Ptr->ForwardLink;\r |
1081f624 | 103 | Count++;\r |
104 | } while ((Ptr != List) && (Count < PcdGet32 (PcdMaximumLinkedListLength)));\r | |
105 | \r | |
106 | //\r | |
107 | // ASSERT() if the linked list is too long\r | |
108 | //\r | |
109 | ASSERT (Count < PcdGet32 (PcdMaximumLinkedListLength));\r | |
e1f414b6 | 110 | }\r |
111 | \r | |
1081f624 | 112 | return TRUE;\r |
e1f414b6 | 113 | }\r |
114 | \r | |
115 | /**\r | |
116 | Initializes the head node of a doubly linked list, and returns the pointer to\r | |
117 | the head node of the doubly linked list.\r | |
118 | \r | |
119 | Initializes the forward and backward links of a new linked list. After\r | |
120 | initializing a linked list with this function, the other linked list\r | |
121 | functions may be used to add and remove nodes from the linked list. It is up\r | |
122 | to the caller of this function to allocate the memory for ListHead.\r | |
123 | \r | |
124 | If ListHead is NULL, then ASSERT().\r | |
125 | \r | |
9aa049d9 | 126 | @param ListHead A pointer to the head node of a new doubly linked list.\r |
e1f414b6 | 127 | \r |
128 | @return ListHead\r | |
129 | \r | |
130 | **/\r | |
131 | LIST_ENTRY *\r | |
132 | EFIAPI\r | |
133 | InitializeListHead (\r | |
2fc60b70 | 134 | IN OUT LIST_ENTRY *ListHead\r |
e1f414b6 | 135 | )\r |
136 | \r | |
137 | {\r | |
2fc60b70 | 138 | ASSERT (ListHead != NULL);\r |
e1f414b6 | 139 | \r |
2fc60b70 | 140 | ListHead->ForwardLink = ListHead;\r |
141 | ListHead->BackLink = ListHead;\r | |
142 | return ListHead;\r | |
e1f414b6 | 143 | }\r |
144 | \r | |
145 | /**\r | |
146 | Adds a node to the beginning of a doubly linked list, and returns the pointer\r | |
147 | to the head node of the doubly linked list.\r | |
148 | \r | |
149 | Adds the node Entry at the beginning of the doubly linked list denoted by\r | |
150 | ListHead, and returns ListHead.\r | |
151 | \r | |
152 | If ListHead is NULL, then ASSERT().\r | |
153 | If Entry is NULL, then ASSERT().\r | |
9aa049d9 | 154 | If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r |
155 | InitializeListHead(), then ASSERT().\r | |
e1f414b6 | 156 | If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number\r |
157 | of nodes in ListHead, including the ListHead node, is greater than or\r | |
158 | equal to PcdMaximumLinkedListLength, then ASSERT().\r | |
159 | \r | |
9aa049d9 | 160 | @param ListHead A pointer to the head node of a doubly linked list.\r |
e1f414b6 | 161 | @param Entry A pointer to a node that is to be inserted at the beginning\r |
162 | of a doubly linked list.\r | |
163 | \r | |
164 | @return ListHead\r | |
165 | \r | |
166 | **/\r | |
167 | LIST_ENTRY *\r | |
168 | EFIAPI\r | |
169 | InsertHeadList (\r | |
2fc60b70 | 170 | IN OUT LIST_ENTRY *ListHead,\r |
171 | IN OUT LIST_ENTRY *Entry\r | |
e1f414b6 | 172 | )\r |
173 | {\r | |
174 | //\r | |
175 | // ASSERT List not too long and Entry is not one of the nodes of List\r | |
176 | //\r | |
1081f624 | 177 | ASSERT (InternalBaseLibIsNodeInList (ListHead, Entry, FALSE));\r |
178 | \r | |
2fc60b70 | 179 | Entry->ForwardLink = ListHead->ForwardLink;\r |
180 | Entry->BackLink = ListHead;\r | |
e1f414b6 | 181 | Entry->ForwardLink->BackLink = Entry;\r |
2fc60b70 | 182 | ListHead->ForwardLink = Entry;\r |
183 | return ListHead;\r | |
e1f414b6 | 184 | }\r |
185 | \r | |
186 | /**\r | |
187 | Adds a node to the end of a doubly linked list, and returns the pointer to\r | |
188 | the head node of the doubly linked list.\r | |
189 | \r | |
190 | Adds the node Entry to the end of the doubly linked list denoted by ListHead,\r | |
191 | and returns ListHead.\r | |
192 | \r | |
193 | If ListHead is NULL, then ASSERT().\r | |
194 | If Entry is NULL, then ASSERT().\r | |
9aa049d9 | 195 | If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or \r |
196 | InitializeListHead(), then ASSERT().\r | |
e1f414b6 | 197 | If PcdMaximumLinkedListLenth is not zero, and prior to insertion the number\r |
198 | of nodes in ListHead, including the ListHead node, is greater than or\r | |
199 | equal to PcdMaximumLinkedListLength, then ASSERT().\r | |
200 | \r | |
9aa049d9 | 201 | @param ListHead A pointer to the head node of a doubly linked list.\r |
e1f414b6 | 202 | @param Entry A pointer to a node that is to be added at the end of the\r |
203 | doubly linked list.\r | |
204 | \r | |
205 | @return ListHead\r | |
206 | \r | |
207 | **/\r | |
208 | LIST_ENTRY *\r | |
209 | EFIAPI\r | |
210 | InsertTailList (\r | |
2fc60b70 | 211 | IN OUT LIST_ENTRY *ListHead,\r |
212 | IN OUT LIST_ENTRY *Entry\r | |
e1f414b6 | 213 | )\r |
214 | {\r | |
215 | //\r | |
216 | // ASSERT List not too long and Entry is not one of the nodes of List\r | |
217 | //\r | |
1081f624 | 218 | ASSERT (InternalBaseLibIsNodeInList (ListHead, Entry, FALSE));\r |
219 | \r | |
2fc60b70 | 220 | Entry->ForwardLink = ListHead;\r |
221 | Entry->BackLink = ListHead->BackLink;\r | |
e1f414b6 | 222 | Entry->BackLink->ForwardLink = Entry;\r |
2fc60b70 | 223 | ListHead->BackLink = Entry;\r |
224 | return ListHead;\r | |
e1f414b6 | 225 | }\r |
226 | \r | |
227 | /**\r | |
228 | Retrieves the first node of a doubly linked list.\r | |
229 | \r | |
9aa049d9 | 230 | Returns the first node of a doubly linked list. List must have been \r |
231 | initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r | |
232 | If List is empty, then List is returned.\r | |
e1f414b6 | 233 | \r |
234 | If List is NULL, then ASSERT().\r | |
9aa049d9 | 235 | If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or \r |
236 | InitializeListHead(), then ASSERT().\r | |
e1f414b6 | 237 | If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r |
238 | in List, including the List node, is greater than or equal to\r | |
239 | PcdMaximumLinkedListLength, then ASSERT().\r | |
240 | \r | |
241 | @param List A pointer to the head node of a doubly linked list.\r | |
242 | \r | |
243 | @return The first node of a doubly linked list.\r | |
244 | @retval NULL The list is empty.\r | |
245 | \r | |
246 | **/\r | |
247 | LIST_ENTRY *\r | |
248 | EFIAPI\r | |
249 | GetFirstNode (\r | |
2fc60b70 | 250 | IN CONST LIST_ENTRY *List\r |
e1f414b6 | 251 | )\r |
252 | {\r | |
253 | //\r | |
254 | // ASSERT List not too long\r | |
255 | //\r | |
1081f624 | 256 | ASSERT (InternalBaseLibIsNodeInList (List, List, FALSE));\r |
e1f414b6 | 257 | \r |
258 | return List->ForwardLink;\r | |
259 | }\r | |
260 | \r | |
261 | /**\r | |
262 | Retrieves the next node of a doubly linked list.\r | |
263 | \r | |
9aa049d9 | 264 | Returns the node of a doubly linked list that follows Node. \r |
265 | List must have been initialized with INTIALIZE_LIST_HEAD_VARIABLE()\r | |
266 | or InitializeListHead(). If List is empty, then List is returned.\r | |
e1f414b6 | 267 | \r |
268 | If List is NULL, then ASSERT().\r | |
269 | If Node is NULL, then ASSERT().\r | |
9aa049d9 | 270 | If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or \r |
271 | InitializeListHead(), then ASSERT().\r | |
e1f414b6 | 272 | If PcdMaximumLinkedListLenth is not zero, and List contains more than\r |
273 | PcdMaximumLinkedListLenth nodes, then ASSERT().\r | |
1081f624 | 274 | If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r |
e1f414b6 | 275 | \r |
276 | @param List A pointer to the head node of a doubly linked list.\r | |
277 | @param Node A pointer to a node in the doubly linked list.\r | |
278 | \r | |
279 | @return Pointer to the next node if one exists. Otherwise a null value which\r | |
280 | is actually List is returned.\r | |
281 | \r | |
282 | **/\r | |
283 | LIST_ENTRY *\r | |
284 | EFIAPI\r | |
285 | GetNextNode (\r | |
2fc60b70 | 286 | IN CONST LIST_ENTRY *List,\r |
287 | IN CONST LIST_ENTRY *Node\r | |
e1f414b6 | 288 | )\r |
289 | {\r | |
290 | //\r | |
291 | // ASSERT List not too long and Node is one of the nodes of List\r | |
292 | //\r | |
1081f624 | 293 | ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));\r |
e1f414b6 | 294 | \r |
295 | return Node->ForwardLink;\r | |
296 | }\r | |
297 | \r | |
298 | /**\r | |
299 | Checks to see if a doubly linked list is empty or not.\r | |
300 | \r | |
301 | Checks to see if the doubly linked list is empty. If the linked list contains\r | |
302 | zero nodes, this function returns TRUE. Otherwise, it returns FALSE.\r | |
303 | \r | |
304 | If ListHead is NULL, then ASSERT().\r | |
9aa049d9 | 305 | If ListHead was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or \r |
306 | InitializeListHead(), then ASSERT().\r | |
e1f414b6 | 307 | If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r |
308 | in List, including the List node, is greater than or equal to\r | |
309 | PcdMaximumLinkedListLength, then ASSERT().\r | |
310 | \r | |
9aa049d9 | 311 | @param ListHead A pointer to the head node of a doubly linked list.\r |
e1f414b6 | 312 | \r |
313 | @retval TRUE The linked list is empty.\r | |
314 | @retval FALSE The linked list is not empty.\r | |
315 | \r | |
316 | **/\r | |
317 | BOOLEAN\r | |
318 | EFIAPI\r | |
319 | IsListEmpty (\r | |
2fc60b70 | 320 | IN CONST LIST_ENTRY *ListHead\r |
e1f414b6 | 321 | )\r |
322 | {\r | |
323 | //\r | |
324 | // ASSERT List not too long\r | |
325 | //\r | |
1081f624 | 326 | ASSERT (InternalBaseLibIsNodeInList (ListHead, ListHead, FALSE));\r |
327 | \r | |
2fc60b70 | 328 | return (BOOLEAN)(ListHead->ForwardLink == ListHead);\r |
e1f414b6 | 329 | }\r |
330 | \r | |
331 | /**\r | |
aa0583c7 | 332 | Determines if a node in a doubly linked list is the head node of a the same\r |
333 | doubly linked list. This function is typically used to terminate a loop that\r | |
334 | traverses all the nodes in a doubly linked list starting with the head node.\r | |
e1f414b6 | 335 | \r |
aa0583c7 | 336 | Returns TRUE if Node is equal to List. Returns FALSE if Node is one of the\r |
337 | nodes in the doubly linked list specified by List. List must have been\r | |
9aa049d9 | 338 | initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r |
e1f414b6 | 339 | \r |
340 | If List is NULL, then ASSERT().\r | |
341 | If Node is NULL, then ASSERT().\r | |
9aa049d9 | 342 | If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(), \r |
343 | then ASSERT().\r | |
e1f414b6 | 344 | If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r |
345 | in List, including the List node, is greater than or equal to\r | |
346 | PcdMaximumLinkedListLength, then ASSERT().\r | |
1081f624 | 347 | If PcdVerifyNodeInList is TRUE and Node is not a node in List and Node is not \r |
348 | equal to List, then ASSERT().\r | |
e1f414b6 | 349 | \r |
350 | @param List A pointer to the head node of a doubly linked list.\r | |
351 | @param Node A pointer to a node in the doubly linked list.\r | |
352 | \r | |
353 | @retval TRUE Node is one of the nodes in the doubly linked list.\r | |
354 | @retval FALSE Node is not one of the nodes in the doubly linked list.\r | |
355 | \r | |
356 | **/\r | |
357 | BOOLEAN\r | |
358 | EFIAPI\r | |
359 | IsNull (\r | |
2fc60b70 | 360 | IN CONST LIST_ENTRY *List,\r |
361 | IN CONST LIST_ENTRY *Node\r | |
e1f414b6 | 362 | )\r |
363 | {\r | |
364 | //\r | |
365 | // ASSERT List not too long and Node is one of the nodes of List\r | |
366 | //\r | |
1081f624 | 367 | ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));\r |
368 | \r | |
e1f414b6 | 369 | return (BOOLEAN)(Node == List);\r |
370 | }\r | |
371 | \r | |
372 | /**\r | |
373 | Determines if a node the last node in a doubly linked list.\r | |
374 | \r | |
375 | Returns TRUE if Node is the last node in the doubly linked list specified by\r | |
376 | List. Otherwise, FALSE is returned. List must have been initialized with\r | |
9aa049d9 | 377 | INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead().\r |
e1f414b6 | 378 | \r |
379 | If List is NULL, then ASSERT().\r | |
380 | If Node is NULL, then ASSERT().\r | |
9aa049d9 | 381 | If List was not initialized with INTIALIZE_LIST_HEAD_VARIABLE() or\r |
382 | InitializeListHead(), then ASSERT().\r | |
e1f414b6 | 383 | If PcdMaximumLinkedListLenth is not zero, and the number of nodes\r |
384 | in List, including the List node, is greater than or equal to\r | |
385 | PcdMaximumLinkedListLength, then ASSERT().\r | |
1081f624 | 386 | If PcdVerifyNodeInList is TRUE and Node is not a node in List, then ASSERT().\r |
e1f414b6 | 387 | \r |
388 | @param List A pointer to the head node of a doubly linked list.\r | |
389 | @param Node A pointer to a node in the doubly linked list.\r | |
390 | \r | |
391 | @retval TRUE Node is the last node in the linked list.\r | |
392 | @retval FALSE Node is not the last node in the linked list.\r | |
393 | \r | |
394 | **/\r | |
395 | BOOLEAN\r | |
396 | EFIAPI\r | |
397 | IsNodeAtEnd (\r | |
2fc60b70 | 398 | IN CONST LIST_ENTRY *List,\r |
399 | IN CONST LIST_ENTRY *Node\r | |
e1f414b6 | 400 | )\r |
401 | {\r | |
402 | //\r | |
403 | // ASSERT List not too long and Node is one of the nodes of List\r | |
404 | //\r | |
1081f624 | 405 | ASSERT (InternalBaseLibIsNodeInList (List, Node, TRUE));\r |
406 | \r | |
e1f414b6 | 407 | return (BOOLEAN)(!IsNull (List, Node) && List->BackLink == Node);\r |
408 | }\r | |
409 | \r | |
410 | /**\r | |
411 | Swaps the location of two nodes in a doubly linked list, and returns the\r | |
412 | first node after the swap.\r | |
413 | \r | |
414 | If FirstEntry is identical to SecondEntry, then SecondEntry is returned.\r | |
415 | Otherwise, the location of the FirstEntry node is swapped with the location\r | |
416 | of the SecondEntry node in a doubly linked list. SecondEntry must be in the\r | |
417 | same double linked list as FirstEntry and that double linked list must have\r | |
9aa049d9 | 418 | been initialized with INTIALIZE_LIST_HEAD_VARIABLE() or InitializeListHead(). \r |
419 | SecondEntry is returned after the nodes are swapped.\r | |
e1f414b6 | 420 | \r |
421 | If FirstEntry is NULL, then ASSERT().\r | |
422 | If SecondEntry is NULL, then ASSERT().\r | |
1081f624 | 423 | If PcdVerifyNodeInList is TRUE and SecondEntry and FirstEntry are not in the \r |
424 | same linked list, then ASSERT().\r | |
e1f414b6 | 425 | If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r |
426 | linked list containing the FirstEntry and SecondEntry nodes, including\r | |
427 | the FirstEntry and SecondEntry nodes, is greater than or equal to\r | |
428 | PcdMaximumLinkedListLength, then ASSERT().\r | |
429 | \r | |
430 | @param FirstEntry A pointer to a node in a linked list.\r | |
431 | @param SecondEntry A pointer to another node in the same linked list.\r | |
2fc60b70 | 432 | \r |
9aa049d9 | 433 | @return SecondEntry.\r |
e1f414b6 | 434 | \r |
435 | **/\r | |
436 | LIST_ENTRY *\r | |
437 | EFIAPI\r | |
438 | SwapListEntries (\r | |
2fc60b70 | 439 | IN OUT LIST_ENTRY *FirstEntry,\r |
440 | IN OUT LIST_ENTRY *SecondEntry\r | |
e1f414b6 | 441 | )\r |
442 | {\r | |
443 | LIST_ENTRY *Ptr;\r | |
444 | \r | |
445 | if (FirstEntry == SecondEntry) {\r | |
446 | return SecondEntry;\r | |
447 | }\r | |
448 | \r | |
449 | //\r | |
450 | // ASSERT Entry1 and Entry2 are in the same linked list\r | |
451 | //\r | |
1081f624 | 452 | ASSERT (InternalBaseLibIsNodeInList (FirstEntry, SecondEntry, TRUE));\r |
453 | \r | |
e1f414b6 | 454 | //\r |
455 | // Ptr is the node pointed to by FirstEntry->ForwardLink\r | |
456 | //\r | |
457 | Ptr = RemoveEntryList (FirstEntry);\r | |
458 | \r | |
459 | //\r | |
24dcb5e5 | 460 | // If FirstEntry immediately follows SecondEntry, FirstEntry will be placed\r |
e1f414b6 | 461 | // immediately in front of SecondEntry\r |
462 | //\r | |
463 | if (Ptr->BackLink == SecondEntry) {\r | |
464 | return InsertTailList (SecondEntry, FirstEntry);\r | |
465 | }\r | |
466 | \r | |
467 | //\r | |
468 | // Ptr == SecondEntry means SecondEntry immediately follows FirstEntry,\r | |
469 | // then there are no further steps necessary\r | |
470 | //\r | |
471 | if (Ptr == InsertHeadList (SecondEntry, FirstEntry)) {\r | |
472 | return Ptr;\r | |
473 | }\r | |
474 | \r | |
475 | //\r | |
476 | // Move SecondEntry to the front of Ptr\r | |
477 | //\r | |
478 | RemoveEntryList (SecondEntry);\r | |
479 | InsertTailList (Ptr, SecondEntry);\r | |
480 | return SecondEntry;\r | |
481 | }\r | |
482 | \r | |
483 | /**\r | |
484 | Removes a node from a doubly linked list, and returns the node that follows\r | |
485 | the removed node.\r | |
486 | \r | |
487 | Removes the node Entry from a doubly linked list. It is up to the caller of\r | |
488 | this function to release the memory used by this node if that is required. On\r | |
489 | exit, the node following Entry in the doubly linked list is returned. If\r | |
490 | Entry is the only node in the linked list, then the head node of the linked\r | |
491 | list is returned.\r | |
492 | \r | |
493 | If Entry is NULL, then ASSERT().\r | |
494 | If Entry is the head node of an empty list, then ASSERT().\r | |
495 | If PcdMaximumLinkedListLength is not zero, and the number of nodes in the\r | |
496 | linked list containing Entry, including the Entry node, is greater than\r | |
497 | or equal to PcdMaximumLinkedListLength, then ASSERT().\r | |
498 | \r | |
9aa049d9 | 499 | @param Entry A pointer to a node in a linked list.\r |
e1f414b6 | 500 | \r |
9aa049d9 | 501 | @return Entry.\r |
e1f414b6 | 502 | \r |
503 | **/\r | |
504 | LIST_ENTRY *\r | |
505 | EFIAPI\r | |
506 | RemoveEntryList (\r | |
2fc60b70 | 507 | IN CONST LIST_ENTRY *Entry\r |
e1f414b6 | 508 | )\r |
509 | {\r | |
510 | ASSERT (!IsListEmpty (Entry));\r | |
1081f624 | 511 | \r |
e1f414b6 | 512 | Entry->ForwardLink->BackLink = Entry->BackLink;\r |
513 | Entry->BackLink->ForwardLink = Entry->ForwardLink;\r | |
514 | return Entry->ForwardLink;\r | |
515 | }\r |