<! -- @ Page {margin: 2 cm} pre. CJK {font-family: "dejavu sans", monospace} p {margin-bottom: 0.21 cm} A: link {so-language: zxx} -->
The list_head function of the kernel is quite clever. Today, I will explain how to delete elements from the list_head linked list.
The review duration of the linked list. If you delete the current element, errors may occur. This is true for linked lists in various libraries in all languages. The same is true for list_head.
<! -- @ Page {margin: 2 cm} p {margin-bottom: 0.21} A: link {so-language: zxx} -->
For example, deleting the current element in Java traversal throws a java. util. concurrentmodificationexception.
See: how to delete multiple elements in a collection in Java http://blog.csdn.net/shendl/archive/2007/12/28/1999907.aspx
Article.
If you use list_for_each to remove the current element from the chain, the system will crash relentlessly. No prompts are displayed. Therefore, such bugs are very difficult to locate.
List_for_each source code:
/** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. */#define list_for_each(pos, head) / for (pos = (head)->next; prefetch(pos->next), pos != (head); / pos = pos->next)
After the list_del leeching element is removed, the next and Prev values are assigned as follows:
/* * These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses * non-initialized list entries. */#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA)#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA
After list_del_init is dechained, both next and Prev are set as their own.
Therefore, after deleting the current element in list_for_each, The next element of the linked list cannot be found correctly.
To delete the current element when traversing the list_head linked list, you must use the list_for_each_safe function instead of the list_for_each function.
List_for_each_safe source code:
/** * list_for_each_safe - iterate over a list safe against removal of list entry * @pos: the &struct list_head to use as a loop cursor. * @n: another &struct list_head to use as temporary storage * @head: the head for your list. */#define list_for_each_safe(pos, n, head) / for (pos = (head)->next, n = pos->next; pos != (head); / pos = n, n = pos->next)
This function RatioList_for_eachThe function has one moreNParameters. This parameter is alsoList_headType.
It saves the next element, so that the current element can be safely deleted without any subsequent element being found.
At the end of the loop,PosPointNElement instead of pointingPosOfNextElement. BecausePosAfter leeching,PosElementNextIt may already be a null pointer, or list_python1
This meaningless value.
IfListIs empty, soPos = NIs still equalHeadThe traversal is over!
ThereforeLisf_for_each_safeFunction TraversalList_headLinked list, you can safely delete the current element.