linux deepin kernel header file parsing (a) - list.h

Code file deepin15.10 / include / list.h


linux kernel provides a doubly-linked list data structure, and comprises a series of interfaces.

List.h contains the header files in the linux / types.h found in the definition of a linked list structure:

struct list_head {
	struct list_head *next, *prev;
};

The image of the logical structure that can be expressed as:

Curiously actually no data field (typically a linked list consists of two parts, a data field, i.e. the data storage portion, and the pointer field for storing the node address portion of the other, there may be something wrong back slowly to after studying)

Structure contains two members, two members are list_head pointer. Precursor (PREV) pointing to the node and subsequent (next).

Defined in the first macro file list.h

#define LIST_HEAD_INIT(name) { &(name), &(name) }

This macro definition is difficult to understand at first glance, LIST_HEAD_INIT () function is called passing a variable name, function is the function takes a variable name address. This is seen from the name of the function to initialize the list. But having read the second sentence macros suddenly see the light.

#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name)

In the phrase in the definition of a macro function LIST_HEAD, function creates a linked list node name, and the name of the predecessor and successor points to himself.

The following declares first function:

static inline void INIT_LIST_HEAD(struct list_head *list)
{
	WRITE_ONCE(list->next, list);
	list->prev = list;
}

I still do not know the specific function of the difference between the front and a macro definition, it is to list the list predecessor and successor points to list themselves. Function WRITE_ONCE () is defined (this function involves memory operations at compile time, and the following READ_ONCE () are the same as for operational safety and cpu read access time of memory) in include / linux / compiler.h in

The following code is to check the validity of the list in Debug mode:

#ifdef CONFIG_DEBUG_LIST
extern bool __list_add_valid(struct list_head *new,
			      struct list_head *prev,
			      struct list_head *next);
extern bool __list_del_entry_valid(struct list_head *entry);
#else
static inline bool __list_add_valid(struct list_head *new,
				struct list_head *prev,
				struct list_head *next)
{
	return true;
}
static inline bool __list_del_entry_valid(struct list_head *entry)
{
	return true;
}
#endif

Document defines the interface list node after a series of operations, one by one to see.

static inline void __list_add(struct list_head *new,
			      struct list_head *prev,
			      struct list_head *next)
{
	if (!__list_add_valid(new, prev, next))
		return;

	next->prev = new;
	new->next = next;
	new->prev = prev;
	WRITE_ONCE(prev->next, new);
}

This function is passed three parameters, namely the address into the address of the node, the insertion position before and after the node:

For example calling function _list_add (& new, & (n), & (n + 1)), the execution result is + new node is inserted between node 1 and node n n:

Step: n + prev 1 of node points to the node address of the new 0x06f

Step two: the new address of the next node n + 1 points to the node of 0x00a

第三步:节点n的next指向节点new,节点new的prev指向节点n


未完。。。

Guess you like

Origin blog.csdn.net/weixin_40771793/article/details/94752018