For a computer student, the Linked List data structure is no longer familiar to us. After all, I have explained it in the "Data Structure" of the university. I believe you have implemented it yourself, it may look like this: (the examples here are from the third edition of Linux kernel design and implementation)
Suppose we have a data structure to describe a member of the dog family.
struct fox{unsigned long tail_length;unsigned long weight;bool is_fantastic;}
The common method to store this structure into a linked list is to embed a linked list pointer in the data structure, for example:
struct fox{unsigned long tail_length;unsigned long weight;bool is_fantastic;struct fox *next;struct fox *prev;}
The resulting linked list is like this:
The Linux kernel method is different. Instead of inserting the data structure into the linked list, it inserts the linked list node into the data structure!
1. Linked List Data Structure
In the past, there were many implementations of linked lists in the kernel. We should choose a simple and efficient linked list to unify them.
The linked list code is declared in the header file <Linux/list. h>. Its data structure is very simple:
struct list_head{struct list_head *next;struct list_head *prev;}
The next Pointer Points to the next linked list node, and the prev Pointer Points to the forward one. However, it seems that they do not have much effect here. What is declared as the specific content of linked list storage? The key is to understand how the list_head structure is used.
struct fox{unsigned long tail_length;unsigned long weight;bool is_fantastic;struct list_head list;}
In the above structure, list. Next in Fox points to the next element, and list. Prev refers to the first element. Now the linked list can be used, but it is obviously not convenient enough. Therefore, the kernel provides a set of linked list operation routines. For example, the list_add () method adds a new node to the linked list. However, these methods have a unified feature: they only accept the list_head structure as the parameter. Using the macro container_of (), we can easily find any variables contained in the parent structure from the linked list pointer. This is because in C language, the variable offset in a given structure is fixed by ABI during compilation.