The difference between the traditional linked list and the Linu kernel list:
Figure A
Figure II
It can be seen that there is no commonality between the various links in the traditional list, because each data domain is different, and the structure of the linked list is embedded into the data domain structure in the Linux kernel, so that the different structures could be connected together.
Link list implementation file path in kernel: include/linux/list.h
Linked list structure definition
struct List_head {
struct List_head *next, *prev;
};
Get Structure Entry address (list_entry)
#define List_entry (PTR, type, member) \
Container_of (PTR, type, member)
Description: type specifies a struct type, member is a member of the struct, and PTR is the same type as member;
#define CONTAINER_OF (PTR, type, member) ({\
Const typeof (((type *) 0)->member) *__mptr = (PTR); \
(Type *) ((char *) __mptr-offsetof (type, member)); })
#define OFFSETOF (Type, MEMBER) ((size_t) & ((TYPE *) 0)->member)
Explanation of Interpretation:
1, typeof to get the type of variable;
2, Const typeof (((type *) 0)->member) *__mptr = (PTR);
Cast 0 to a pointer of type types (where 0 can be used with other numbers), and then get the type of the member member in the type (where the type is a), const a *__mptr= (PTR);
3, #define OFFSETOF (Type, MEMBER) ((size_t) & ((type *) 0)->member)
Gets the offset of the member in the structure, note here ((type *) 0) Here must be 0 can not be another number, because this defines a pointer to its base address of 0, then ((size_t) & ((type *) 0)->member) The expression is actually the offset of the member member in the type.
Traversal of a linked list
#define LIST_FOR_EACH_ENTRY (POS, head, member) \
for (pos = list_entry (head)->next, typeof (*pos), member); \
&pos->member! = (head); \
pos = List_entry (Pos->member.next, typeof (*pos), member))
Initializing a linked list member
#define LIST_HEAD_INIT (name) {& (name), & (name)}
#define LIST_HEAD (name) \
struct List_head name = List_head_init (name)
static inline void Init_list_head (struct list_head *list)
{
List->next = list;
List->prev = list;
}
Note: Both List_head_init and List_head refer to each of the two members of the list, but list_head create a List_head structure object named parameter name;
Add list node
static inline void __list_add (struct list_head *new,
struct List_head *prev,
struct List_head *next)
{
Next->prev = new;
New->next = Next;
New->prev = prev;
Prev->next = new;
}
Deletion of linked list nodes
static inline void __list_del (struct list_head * prev, struct list_head * next)
{
Next->prev = prev;
Prev->next = Next;
}
Linux kernel Series (a) linked list of kernel data structures