Linux Kernel (10)-linked list in the kernel

Source: Internet
Author: User

In the morning to work in the subway line, to the company downstairs waiting for the elevator to line up, lunch to line up, after work to pursue a girl also to line up, even on the internet to download a short film of what door to queue, every time you see the crowd lined up a long time, only really realize that they are the descendants of the dragon. So let's talk about the queue (linked list).

The purpose of using the list is very clear, because there are a lot of things to do, so put it into the list, one thing to deal with. For example in the USB subsystem, the U disk constantly submit URB request, USB keyboard also submitted, USB mouse also submitted, that USB host controller How can I cope with it? Very simple, build a linked list, and then every time you commit is inserted into the inside, and then the USB host controller Unified to dispatch, one to execute. Here strong proof, rectification Big Brother's C program design is we learn the powerful weapon of Linux, the book in the introduction of the list is undoubtedly wise, tan eldest brother, you are not a person in the fight!

The implementation of the linked list in the kernel is located in the Include/linux/list.h file, and the definition of the linked list data structure is simple.

+ struct List_head {

A struct list_head *next, *prev;

23};

The List_head structure contains two pointers to the list_head structure, prev and next, so that the linked list in the kernel is actually a doubly linked list (typically a double-loop list).

In general, the list of links that we know in the data structure class is defined in this way (in the case of a single-linked list):

struct List_node {

struct List_node *next;

Elemtype data;

};

Using linked lists in this way, for each data type, define their own linked list structure. The list in the kernel differs from this, and it does not have a data field, it does not contain data in the linked list structure, but contains the linked list in the structure that describes the data type.

For example, in a hub driver using a struct usb_hub to describe the hub device, the hub needs to handle a series of events, such as when a device is detected to be connected, it executes some code to initialize the device, so the hub creates a linked list to handle various events, the structure of the linked list.

(1) Declaration and initialization.

There are two ways to declare a list, one for static initialization at compile time using the List_head macro, and one to initialize at run time with Init_list_head ().

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

26

#define LIST_HEAD (name)/

list_head struct name = List_head_init (name)

29

static inline void Init_list_head (struct list_head *list)

31 {

List->next = list;

List->prev = list;

34}

Either way, the two pointers next and prev of the newly generated linked header are initialized to point to themselves.

(2) Determine if the linked list is empty.

298 Static inline int list_empty (const struct List_head *head)

299 {

return head->next = = head;

301}

(3) Insert.

With a linked list, it is natural to add things to the inside, minus things. Like each of us every day in the walk, and come out, like a dream is not a dream. Everything is casual. Go into the year-round, come out is spring and autumn. The two functions of List_add () and List_add_tail () are to add something to the queue.

List_add static inline void (struct list_head *new, struct list_head *head)

68 {

__list_add (New, head, Head->next);

70}

static inline void List_add_tail (struct list_head *new, struct list_head *head)

85 {

__list_add (New, head->prev, head);

87}

where List_add () inserts data into the head, List_add_tail () inserts the data after Head->prev. In fact, for the loop linked list, the table header of next, Prev respectively to the first and last node in the list, so the difference between list_add () and List_add_tail () is not big.

(4) Delete.

It's a piece of cake to read the code of these lists after rectification that book. Again to see the next List_del_init (), the elements can not only add no less, the useless elements should be deleted, the space to free up to others. Guo said, the warmth of my life is so much, I gave you all, but you left me, you tell me how to laugh at others ...

The elements in the list cannot be added or lost, and the unused elements should be removed.

254 Static inline void List_del_init (struct list_head *entry)

255 {

__list_del (Entry->prev, Entry->next);

257 Init_list_head (entry);

258}

List_del_init () deletes an element from the list and initializes it.

(5) traversal.

The list in the kernel simply preserves the address of the list_head structure, how do we get through it or take a list of node real data items? This will refer to all the operations in the list, the most important Super Classic List_entry macro, we can easily get a list node data.

425 #define List_entry (PTR, type, member)/

426 container_of (PTR, type, member)

I believe that list_entry () This macro in the Linux kernel code position, is equivalent to the advertising word in the Ningjing Sandi washing more health, the equivalent of a beautiful woman Rosamund Kwan a minute easy to do women, which are familiar including women, is the classic classic. If you say you do not know List_entry (), then you must not tell people you understand the Linux kernel, just like you do not know Chen Wen do not know that you are at all embarrassed to tell people you have been studying, to know that each postgraduate is left-handed one of the Chen Wendeng right-handed one of the hands of Ru Fen.

Unfortunately, about List_entry, this rectification teacher's book does not have, of course, you can not accuse rectification book, no good books can be all-encompassing.

With regard to List_entry (), let's take a look at the example of the hub driver, and when we really have to deal with the hub event, we need to know exactly which hub is triggering the event. The function of List_entry is to get the struct USB_HUB structure variables corresponding to the struct List_head event_list. For example, the following four lines of code:

struct List_head *tmp;

struct Usb_hub *hub;

TMP = Hub_event_list.next;

Hub = List_entry (tmp, struct usb_hub, event_list);

Take one out of the global list hub_event_list, called TMP, and then pass TMP to get the struct Usb_hub it corresponds to.

Linux Kernel (10)-linked list in the kernel

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.